diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm index 3656a2d3681..a1ed1bf3648 100644 --- a/code/ATMOSPHERICS/atmospherics.dm +++ b/code/ATMOSPHERICS/atmospherics.dm @@ -39,7 +39,7 @@ Pipelines + Other Objects -> Pipe network pipe_color = null ..() -/obj/machinery/atmospherics/attackby(atom/A, mob/user as mob) +/obj/machinery/atmospherics/attackby(atom/A, mob/user as mob, params) if(istype(A, /obj/item/device/pipe_painter)) return ..() diff --git a/code/ATMOSPHERICS/chiller.dm b/code/ATMOSPHERICS/chiller.dm index 3aa8b0af271..80b0a06e9c6 100644 --- a/code/ATMOSPHERICS/chiller.dm +++ b/code/ATMOSPHERICS/chiller.dm @@ -9,8 +9,6 @@ set_temperature = 20 // in celcius, add T0C for kelvin var/cooling_power = 40000 - flags = FPRINT - /obj/machinery/space_heater/air_conditioner/New() ..() @@ -49,15 +47,15 @@ cell.emp_act(severity) ..(severity) -/obj/machinery/space_heater/air_conditioner/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/weapon/cell)) +/obj/machinery/space_heater/air_conditioner/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/weapon/stock_parts/cell)) if(open) if(cell) user << "There is already a power cell inside." return else // insert cell - var/obj/item/weapon/cell/C = usr.get_active_hand() + var/obj/item/weapon/stock_parts/cell/C = usr.get_active_hand() if(istype(C)) user.drop_item() cell = C @@ -96,11 +94,11 @@ // AUTOFIXED BY fix_string_idiocy.py // C:\Users\Rob\Documents\Projects\vgstation13\code\ATMOSPHERICS\chiller.dm:95: dat += "Power Level: [cell ? round(cell.percent(),1) : 0]%

" dat += {"Power Level: [cell ? round(cell.percent(),1) : 0]%

- Set Temperature: - - + Set Temperature: + - - - [temp]°C - + + [temp]°C + + +
"} // END AUTOFIX user.set_machine(src) @@ -138,7 +136,7 @@ if("cellinstall") if(open && !cell) - var/obj/item/weapon/cell/C = usr.get_active_hand() + var/obj/item/weapon/stock_parts/cell/C = usr.get_active_hand() if(istype(C)) usr.drop_item() cell = C diff --git a/code/ATMOSPHERICS/components/binary_devices/circulator.dm b/code/ATMOSPHERICS/components/binary_devices/circulator.dm index 0ac8ab62997..843b7dc6518 100644 --- a/code/ATMOSPHERICS/components/binary_devices/circulator.dm +++ b/code/ATMOSPHERICS/components/binary_devices/circulator.dm @@ -70,7 +70,7 @@ return 1 -/obj/machinery/atmospherics/binary/circulator/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/atmospherics/binary/circulator/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/wrench)) anchored = !anchored user << "\blue You [anchored ? "secure" : "unsecure"] the bolts holding [src] to the floor." diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm index 4766883a645..9da08d5b117 100644 --- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm +++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm @@ -152,7 +152,7 @@ src.updateUsrDialog() return -/obj/machinery/atmospherics/binary/passive_gate/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) +/obj/machinery/atmospherics/binary/passive_gate/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params) if (!istype(W, /obj/item/weapon/wrench)) return ..() if (on) diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm index 944ed53de16..6091f7240cc 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -184,7 +184,7 @@ Thus, the two variables affect pump operation are set in New(): if(old_stat != stat) update_icon() -/obj/machinery/atmospherics/binary/pump/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) +/obj/machinery/atmospherics/binary/pump/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params) if (!istype(W, /obj/item/weapon/wrench)) return ..() if (!(stat & NOPOWER) && on) diff --git a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm index 65eaabe40ab..cd30bf8cd2f 100644 --- a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm @@ -171,7 +171,7 @@ Thus, the two variables affect pump operation are set in New(): if(old_stat != stat) update_icon() -/obj/machinery/atmospherics/binary/volume_pump/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) +/obj/machinery/atmospherics/binary/volume_pump/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params) if (!istype(W, /obj/item/weapon/wrench)) return ..() if (!(stat & NOPOWER) && on) diff --git a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm index ab97a6f2fd8..dbc1e1420b7 100644 --- a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm +++ b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm @@ -70,7 +70,7 @@ if(old_stat != stat) update_icon() -/obj/machinery/atmospherics/omni/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) +/obj/machinery/atmospherics/omni/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params) if(!istype(W, /obj/item/weapon/wrench)) return ..() diff --git a/code/ATMOSPHERICS/components/portables_connector.dm b/code/ATMOSPHERICS/components/portables_connector.dm index 09fe000ec25..fda49cd6efc 100644 --- a/code/ATMOSPHERICS/components/portables_connector.dm +++ b/code/ATMOSPHERICS/components/portables_connector.dm @@ -133,11 +133,11 @@ return null -/obj/machinery/atmospherics/portables_connector/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) +/obj/machinery/atmospherics/portables_connector/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params) if (!istype(W, /obj/item/weapon/wrench)) return ..() if (connected_device) - user << "\red You cannot unwrench this [src], dettach [connected_device] first." + user << "\red You cannot unwrench this [src], detach [connected_device] first." return 1 if (locate(/obj/machinery/portable_atmospherics, src.loc)) return 1 diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm index 677e5d4de2a..24ce446edb7 100755 --- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm @@ -156,7 +156,7 @@ Filter types: set_frequency(frequency) ..() -/obj/machinery/atmospherics/trinary/filter/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) +/obj/machinery/atmospherics/trinary/filter/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params) if (!istype(W, /obj/item/weapon/wrench)) return ..() var/datum/gas_mixture/int_air = return_air() diff --git a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm index 228be72020d..841e9761231 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm @@ -114,7 +114,7 @@ return 1 -/obj/machinery/atmospherics/trinary/mixer/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) +/obj/machinery/atmospherics/trinary/mixer/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params) if (!istype(W, /obj/item/weapon/wrench)) return ..() var/datum/gas_mixture/int_air = return_air() diff --git a/code/ATMOSPHERICS/components/tvalve.dm b/code/ATMOSPHERICS/components/tvalve.dm index 22f9171ba74..da4a9cbb7bd 100644 --- a/code/ATMOSPHERICS/components/tvalve.dm +++ b/code/ATMOSPHERICS/components/tvalve.dm @@ -358,7 +358,7 @@ else go_to_side() -/obj/machinery/atmospherics/tvalve/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) +/obj/machinery/atmospherics/tvalve/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params) if (!istype(W, /obj/item/weapon/wrench)) return ..() if (istype(src, /obj/machinery/atmospherics/tvalve/digital)) diff --git a/code/ATMOSPHERICS/components/unary/heat_exchanger.dm b/code/ATMOSPHERICS/components/unary/heat_exchanger.dm index cd92aa19d36..54e49e89378 100644 --- a/code/ATMOSPHERICS/components/unary/heat_exchanger.dm +++ b/code/ATMOSPHERICS/components/unary/heat_exchanger.dm @@ -65,7 +65,7 @@ return 1 - attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) + attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params) if (!istype(W, /obj/item/weapon/wrench)) return ..() var/turf/T = src.loc diff --git a/code/ATMOSPHERICS/components/unary/thermal_plate.dm b/code/ATMOSPHERICS/components/unary/thermal_plate.dm index 605af38671e..1f5c78de6cf 100644 --- a/code/ATMOSPHERICS/components/unary/thermal_plate.dm +++ b/code/ATMOSPHERICS/components/unary/thermal_plate.dm @@ -68,7 +68,7 @@ icon_state = "[prefix]off" return - attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) + attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params) if (!istype(W, /obj/item/weapon/wrench)) return ..() var/turf/T = src.loc diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm index 68e0c52892a..d2092ce7e54 100644 --- a/code/ATMOSPHERICS/components/unary/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm @@ -307,7 +307,7 @@ update_icon() return -/obj/machinery/atmospherics/unary/vent_pump/attackby(obj/item/W, mob/user) +/obj/machinery/atmospherics/unary/vent_pump/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/WT = W if (WT.remove_fuel(0,user)) @@ -343,7 +343,7 @@ if(old_stat != stat) update_icon() -/obj/machinery/atmospherics/unary/vent_pump/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) +/obj/machinery/atmospherics/unary/vent_pump/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params) if (!istype(W, /obj/item/weapon/wrench)) return ..() if (!(stat & NOPOWER) && on) diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm index b62139cf508..05d60c80c96 100644 --- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm @@ -276,7 +276,7 @@ if(old_stat != stat) update_icon() -/obj/machinery/atmospherics/unary/vent_scrubber/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) +/obj/machinery/atmospherics/unary/vent_scrubber/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params) if (!istype(W, /obj/item/weapon/wrench)) return ..() if (!(stat & NOPOWER) && on) diff --git a/code/ATMOSPHERICS/components/valve.dm b/code/ATMOSPHERICS/components/valve.dm index e8b99a9fb99..d004239acd9 100644 --- a/code/ATMOSPHERICS/components/valve.dm +++ b/code/ATMOSPHERICS/components/valve.dm @@ -299,7 +299,7 @@ else open() -/obj/machinery/atmospherics/valve/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) +/obj/machinery/atmospherics/valve/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params) if (!istype(W, /obj/item/weapon/wrench)) return ..() if (istype(src, /obj/machinery/atmospherics/valve/digital) && src:frequency) diff --git a/code/ATMOSPHERICS/he_pipes.dm b/code/ATMOSPHERICS/he_pipes.dm index 15774f99c2f..0f9a38b09b3 100644 --- a/code/ATMOSPHERICS/he_pipes.dm +++ b/code/ATMOSPHERICS/he_pipes.dm @@ -54,11 +54,11 @@ if(target.initialize_directions_he & get_dir(target,src)) node2 = target break - + if(!node1 && !node2) del(src) return - + update_icon() return @@ -105,10 +105,10 @@ if(target.initialize_directions_he & get_dir(target,src)) node2 = target break - + if(!node1 && !node2) - del(src) - return + qdel(src) + return update_icon() return diff --git a/code/ATMOSPHERICS/pipes.dm b/code/ATMOSPHERICS/pipes.dm index cc939c35dfe..b303d7d31f4 100644 --- a/code/ATMOSPHERICS/pipes.dm +++ b/code/ATMOSPHERICS/pipes.dm @@ -55,14 +55,15 @@ return parent.return_network(reference) -/obj/machinery/atmospherics/pipe/Del() + +/obj/machinery/atmospherics/pipe/Destroy() del(parent) - if(air_temporary) + if(air_temporary && loc) loc.assume_air(air_temporary) ..() -/obj/machinery/atmospherics/pipe/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) +/obj/machinery/atmospherics/pipe/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params) if (istype(src, /obj/machinery/atmospherics/pipe/tank)) return ..() if (istype(src, /obj/machinery/atmospherics/pipe/vent)) @@ -70,7 +71,7 @@ if(istype(W,/obj/item/device/pipe_painter)) return 0 - + if (istype(W, /obj/item/device/pipe_freezer)) if(!src.frozen) // If the pipe is not already frozen user << "\red You begin to freeze the [src]" @@ -88,7 +89,7 @@ "You hear dripping water.") add_fingerprint(user) - return 1 + return 1 if (!istype(W, /obj/item/weapon/wrench)) return ..() @@ -96,7 +97,7 @@ if (level==1 && isturf(T) && T.intact) user << "\red You must remove the plating first." return 1 - + var/datum/gas_mixture/int_air = return_air() var/datum/gas_mixture/env_air = loc.return_air() if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE) @@ -129,7 +130,7 @@ /* /obj/machinery/atmospherics/pipe/add_underlay(var/obj/machinery/atmospherics/node, var/direction) - if(istype(src, /obj/machinery/atmospherics/pipe/tank)) //todo: move tanks to unary devices + if(istype(src, /obj/machinery/atmospherics/pipe/tank)) //todo: move tanks to unary devices return ..() if(node) @@ -182,7 +183,7 @@ /obj/machinery/atmospherics/pipe/simple/New() ..() - + // Pipe colors and icon states are handled by an image cache - so color and icon should // be null. For mapping purposes color is defined in the object definitions. icon = null @@ -242,7 +243,7 @@ else if(dir==12) dir = 4 -/obj/machinery/atmospherics/pipe/simple/Del() +/obj/machinery/atmospherics/pipe/simple/Destroy() if(node1) node1.disconnect(src) if(node2) @@ -276,7 +277,7 @@ if (meter.target == src) new /obj/item/pipe_meter(T) del(meter) - del(src) + qdel(src) else if(node1 && node2) overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, pipe_icon + "intact" + icon_connect_type) else @@ -315,7 +316,7 @@ break if(!node1 && !node2) - del(src) + qdel(src) return var/turf/T = get_turf(src) @@ -359,7 +360,7 @@ layer = 2.39 icon_connect_type = "-supply" color = PIPE_COLOR_BLUE - + /obj/machinery/atmospherics/pipe/simple/visible/yellow color = PIPE_COLOR_YELLOW @@ -394,7 +395,7 @@ layer = 2.39 icon_connect_type = "-supply" color = PIPE_COLOR_BLUE - + /obj/machinery/atmospherics/pipe/simple/visible/universal name="Universal pipe adapter" desc = "An adapter for regular, supply and scrubbers pipes" @@ -567,7 +568,7 @@ else . = PROCESS_KILL -/obj/machinery/atmospherics/pipe/manifold/Del() +/obj/machinery/atmospherics/pipe/manifold/Destroy() if(node1) node1.disconnect(src) if(node2) @@ -620,19 +621,19 @@ if (meter.target == src) new /obj/item/pipe_meter(T) del(meter) - del(src) + qdel(src) else overlays.Cut() overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "core" + icon_connect_type) overlays += icon_manager.get_atmos_icon("manifold", , , "clamps" + icon_connect_type) underlays.Cut() - + var/turf/T = get_turf(src) var/list/directions = list(NORTH, SOUTH, EAST, WEST) var/node1_direction = get_dir(src, node1) var/node2_direction = get_dir(src, node2) var/node3_direction = get_dir(src, node3) - + directions -= dir directions -= add_underlay(T,node1,node1_direction,icon_connect_type) @@ -692,7 +693,7 @@ break if (node3) break - + if(!node1 && !node2 && !node3) del(src) return @@ -804,7 +805,7 @@ else . = PROCESS_KILL -/obj/machinery/atmospherics/pipe/manifold4w/Del() +/obj/machinery/atmospherics/pipe/manifold4w/Destroy() if(node1) node1.disconnect(src) if(node2) @@ -866,13 +867,13 @@ if (meter.target == src) new /obj/item/pipe_meter(T) del(meter) - del(src) + qdel(src) else overlays.Cut() overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "4way" + icon_connect_type) overlays += icon_manager.get_atmos_icon("manifold", , , "clamps_4way" + icon_connect_type) underlays.Cut() - + /* var/list/directions = list(NORTH, SOUTH, EAST, WEST) @@ -884,7 +885,7 @@ for(var/D in directions) add_underlay(,D) */ - + var/turf/T = get_turf(src) var/list/directions = list(NORTH, SOUTH, EAST, WEST) var/node1_direction = get_dir(src, node1) @@ -948,7 +949,7 @@ src.connected_to = c node4 = target break - + if(!node1 && !node2 && !node3&& !node4) del(src) return @@ -1059,7 +1060,7 @@ ..() else . = PROCESS_KILL -/obj/machinery/atmospherics/pipe/cap/Del() +/obj/machinery/atmospherics/pipe/cap/Destroy() if(node) node.disconnect(src) @@ -1176,7 +1177,7 @@ else . = PROCESS_KILL -/obj/machinery/atmospherics/pipe/tank/Del() +/obj/machinery/atmospherics/pipe/tank/Destroy() if(node1) node1.disconnect(src) @@ -1220,7 +1221,7 @@ return null -/obj/machinery/atmospherics/pipe/tank/attackby(var/obj/item/W as obj, var/mob/user as mob) +/obj/machinery/atmospherics/pipe/tank/attackby(var/obj/item/W as obj, var/mob/user as mob, params) if(istype(W, /obj/item/device/pipe_painter)) return @@ -1263,7 +1264,7 @@ air_temporary.oxygen = (25*ONE_ATMOSPHERE*O2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature) air_temporary.nitrogen = (25*ONE_ATMOSPHERE*N2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature) - ..() + ..() icon_state = "air" /obj/machinery/atmospherics/pipe/tank/oxygen @@ -1376,7 +1377,7 @@ else parent.mingle_with_turf(loc, volume) -/obj/machinery/atmospherics/pipe/vent/Del() +/obj/machinery/atmospherics/pipe/vent/Destroy() if(node1) node1.disconnect(src) diff --git a/code/ZAS/Airflow.dm b/code/ZAS/Airflow.dm index 1b2296bffd9..0b153c75809 100644 --- a/code/ZAS/Airflow.dm +++ b/code/ZAS/Airflow.dm @@ -8,11 +8,13 @@ mob/proc/airflow_stun() if(stat == 2) return 0 if(last_airflow_stun > world.time - vsc.airflow_stun_cooldown) return 0 + if(!(status_flags & CANSTUN) && !(status_flags & CANWEAKEN)) - src << "\blue You stay upright as the air rushes past you." + src << "You stay upright as the air rushes past you." return 0 - if(weakened <= 0) src << "\red The sudden rush of air knocks you over!" - weakened = max(weakened,5) + if(!lying) + src << "The sudden rush of air knocks you over!" + Weaken(5) last_airflow_stun = world.time mob/living/silicon/airflow_stun() @@ -22,16 +24,9 @@ mob/living/carbon/metroid/airflow_stun() return mob/living/carbon/human/airflow_stun() - if(last_airflow_stun > world.time - vsc.airflow_stun_cooldown) return 0 - if(buckled) return 0 if(shoes) if(shoes.flags & NOSLIP) return 0 - if(!(status_flags & CANSTUN) && !(status_flags & CANWEAKEN)) - src << "\blue You stay upright as the air rushes past you." - return 0 - if(weakened <= 0) src << "\red The sudden rush of air knocks you over!" - weakened = max(weakened,rand(1,5)) - last_airflow_stun = world.time + ..() atom/movable/proc/check_airflow_movable(n) @@ -84,10 +79,8 @@ obj/item/check_airflow_movable(n) if(istype(src, /mob/living/carbon/human)) if(src:buckled) return - if(src:shoes) - if(istype(src:shoes, /obj/item/clothing/shoes/magboots)) - if(src:shoes.flags & NOSLIP) - return + if(src:shoes && src:shoes.flags & NOSLIP) + return src << "\red You are sucked away by airflow!" var/airflow_falloff = 9 - ul_FalloffAmount(airflow_dest) //It's a fast falloff calc. Very useful. if(airflow_falloff < 1) @@ -148,10 +141,8 @@ obj/item/check_airflow_movable(n) if(istype(src, /mob/living/carbon/human)) if(src:buckled) return - if(src:shoes) - if(istype(src:shoes, /obj/item/clothing/shoes/magboots)) - if(src:shoes.flags & NOSLIP) - return + if(src:shoes && src:shoes.flags & NOSLIP) + return src << "\red You are pushed away by airflow!" last_airflow = world.time var/airflow_falloff = 9 - ul_FalloffAmount(airflow_dest) //It's a fast falloff calc. Very useful. @@ -207,7 +198,8 @@ mob/airflow_hit(atom/A) for(var/mob/M in hearers(src)) M.show_message("\red \The [src] slams into \a [A]!",1,"\red You hear a loud slam!",2) playsound(src.loc, "smash.ogg", 25, 1, -1) - weakened = max(weakened, (istype(A,/obj/item) ? A:w_class : rand(1,5))) //Heheheh + var/weak_amt = istype(A,/obj/item) ? A:w_class : rand(1,5) //Heheheh + Weaken(weak_amt) . = ..() obj/airflow_hit(atom/A) @@ -239,10 +231,10 @@ mob/living/carbon/human/airflow_hit(atom/A) apply_damage(b_loss/3, BRUTE, "groin", blocked, 0, "Airflow") if(airflow_speed > 10) - paralysis += round(airflow_speed * vsc.airflow_stun) - stunned = max(stunned,paralysis + 3) + Paralyse(round(airflow_speed * vsc.airflow_stun)) + Stun(paralysis + 3) else - stunned += round(airflow_speed * vsc.airflow_stun/2) + Stun(round(airflow_speed * vsc.airflow_stun/2)) . = ..() zone/proc/movables() @@ -253,7 +245,7 @@ zone/proc/movables() continue . += A -//ULTRALIGHT - only file where this is still used, hence why it's in here +//ULTRALIGHT - only file where this is still used, hence why it's in here #define UL_I_FALLOFF_SQUARE 0 #define UL_I_FALLOFF_ROUND 1 #define ul_FalloffStyle UL_I_FALLOFF_ROUND // Sets the lighting falloff to be either squared or circular. diff --git a/code/ZAS/Atom.dm b/code/ZAS/Atom.dm index b4d1de20af4..fdc187e0e5f 100644 --- a/code/ZAS/Atom.dm +++ b/code/ZAS/Atom.dm @@ -30,6 +30,16 @@ atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0) return 1 +//Convenience function for atoms to update turfs they occupy +/atom/movable/proc/update_nearby_tiles(need_rebuild) + if(!air_master) + return 0 + + for(var/turf/simulated/turf in locs) + air_master.mark_for_update(turf) + + return 1 + //Basically another way of calling CanPass(null, other, 0, 0) and CanPass(null, other, 1.5, 1). //Returns: // 0 - Not blocked diff --git a/code/ZAS/Fire.dm b/code/ZAS/Fire.dm index 6ab559732b4..dfc78987eb3 100644 --- a/code/ZAS/Fire.dm +++ b/code/ZAS/Fire.dm @@ -66,11 +66,42 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh) icon = 'icons/effects/fire.dmi' icon_state = "1" - l_color = "#ED9200" + l_color = "#010000" layer = TURF_LAYER var/firelevel = 10000 //Calculated by gas_mixture.calculate_firelevel() +/obj/fire/proc/GenColor(var/datum/gas_mixture/ac) + var/temperature = ac.temperature + //All temperatures are in Kelvin for the color assignment + if(temperature > 9000) + //rainbow, wtf? + l_color = pick("#0092ED", "#EDEDED", "#ED9200", "#ED00ED", "#0000ED", "#010000", "#00EDED", "#EDED00", "#ED0000") + else if(temperature >= 7150) + //dark blue + l_color = "#0000ED" + else if(temperature >= 5300) + //blue + l_color = "#0092ED" + else if(temperature >= 1800) + //cyan + l_color = "#00EDED" + else if(temperature >= 1500) + //white + l_color = "#EDEDED" + else if(temperature >= 1300) + //yellow + l_color = "#EDED00" + else if(temperature >= 1100) + //orange + l_color = "#ED9200" + else if(temperature >= 75) + //red + l_color = "#ED0000" + else + //black fire, go atmos! + l_color = "#010000" + /obj/fire/process() . = 1 @@ -114,10 +145,10 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh) icon_state = "3" SetLuminosity(7) else if(firelevel > 2.5) - icon_state = "2" + icon_state = "3" SetLuminosity(5) else - icon_state = "1" + icon_state = "3" SetLuminosity(3) //im not sure how to implement a version that works for every creature so for now monkeys are firesafe @@ -130,6 +161,9 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh) // Burn the turf, too. S.fire_act(air_contents, air_contents.temperature, air_contents.return_volume()) + //Update color of the fire + src.GenColor(air_contents) + //spread for(var/direction in cardinal) var/turf/simulated/enemy_tile = get_step(S, direction) diff --git a/code/__HELPERS/constants.dm b/code/__HELPERS/constants.dm new file mode 100644 index 00000000000..f7db3166605 --- /dev/null +++ b/code/__HELPERS/constants.dm @@ -0,0 +1,2 @@ +var/global/const/TICKS_IN_DAY = 864000 +var/global/const/TICKS_IN_SECOND = 10 \ No newline at end of file diff --git a/code/__HELPERS/experimental.dm b/code/__HELPERS/experimental.dm index 0966261563b..da9c2a17446 100644 --- a/code/__HELPERS/experimental.dm +++ b/code/__HELPERS/experimental.dm @@ -1,5 +1,5 @@ /* - * Experimental procs by ESwordTheCat. + * Experimental procs by ESwordTheCat! */ /* @@ -15,7 +15,7 @@ * -1, parameter B is not a char * -2, parameter A is not a string */ -/proc/EgijkAeN(const/A, const/B) +/proc/strpos(const/A, const/B) if (istext(A) == 0 || length(A) < 1) return -2 @@ -31,29 +31,24 @@ . = i i = findtext(A, B, i + 1) -/obj/machinery/proc/getArea() - var/area/A = loc.loc - - if (A != myArea) - myArea = A - - . = myArea - /** * Object pooling. * * If this file is named experimental, * well treat this implementation as experimental experimental (redundancy intended). * - * WARNING, only supports /mob and /obj. + * WARNING, only supports /atom/movable (/mob and /obj) */ // Uncomment to show debug messages. //#define DEBUG_OBJECT_POOL -#define MAINTAINING_OBJECT_POOL_COUNT 20 +#define MAINTAINING_OBJECT_POOL_COUNT 500 -var/list/masterPool = list() +var/global/list/masterPool = new + +// Read-only or compile-time vars and special exceptions. +var/list/exclude = list("inhand_states", "loc", "locs", "parent_type", "vars", "verbs", "type", "x", "y", "z") /* * @args @@ -62,27 +57,35 @@ var/list/masterPool = list() * * Example call: getFromPool(/obj/item/weapon/shard, loc) */ -/proc/getFromPool(const/A, const/B) - if (isnull(masterPool[A])) +/proc/getFromPool() + var/A = args[1] + var/list/B = list() + B += (args - A) + if(length(masterPool["[A]"]) <= 0) #ifdef DEBUG_OBJECT_POOL - world << "DEBUG_OBJECT_POOL: new proc has been called ([A])." + world << text("DEBUG_OBJECT_POOL: new proc has been called ([]).", A) #endif + //so the GC knows we're pooling this type. + if(isnull(masterPool["[A]"])) + masterPool["[A]"] = list(new A) + if(B && B.len) + return new A(arglist(B)) + else + return new A() - return new A(B) - - var/atom/movable/Object = masterPool[A][1] - masterPool[A] -= Object - var/objectLength = length(masterPool[A]) + var/atom/movable/O = masterPool["[A]"][1] + masterPool["[A]"] -= O #ifdef DEBUG_OBJECT_POOL - world << "DEBUG_OBJECT_POOL: getFromPool([A]) [objectLength] left." + world << text("DEBUG_OBJECT_POOL: getFromPool([]) [] left.", A, length(masterPool[A])) #endif - - if (!objectLength) - masterPool[A] = null - - Object.loc = B - return Object + if(!O || !istype(O)) + O = new A(arglist(B)) + else + if(length(B)) + O.loc = B[1] + O.New(arglist(B)) + return O /* * @args @@ -93,31 +96,26 @@ var/list/masterPool = list() * * Example call: returnToPool(src) */ -/proc/returnToPool(const/A) - if (!istype(A, /atom/movable)) - return -1 +/proc/returnToPool(const/atom/movable/AM) + if(istype(AM.loc,/mob/living)) + var/mob/living/L = AM.loc + L.unEquip(AM) + if(length(masterPool["[AM.type]"]) > MAINTAINING_OBJECT_POOL_COUNT) + #ifdef DEBUG_OBJECT_POOL + world << text("DEBUG_OBJECT_POOL: returnToPool([]) exceeds [] discarding...", AM.type, MAINTAINING_OBJECT_POOL_COUNT) + #endif - var/atom/movable/Object = A - Object.resetVariables() + qdel(AM, 1) + return - switch(length(masterPool[Object.type])) - if (MAINTAINING_OBJECT_POOL_COUNT to 1.#INF) - #ifdef DEBUG_OBJECT_POOL - world << "DEBUG_OBJECT_POOL: returnToPool([Object.type]) exceeds [num2text(MAINTAINING_OBJECT_POOL_COUNT)] discarding..." - #endif + if(isnull(masterPool["[AM.type]"])) + masterPool["[AM.type]"] = list() - return - if (0) // In a numeric context (like a mathematical operation), null evaluates to 0. - #ifdef DEBUG_OBJECT_POOL - world << "DEBUG_OBJECT_POOL: [Object.type] pool is empty, recreating pool." - #endif - - masterPool[Object.type] = list() - - masterPool[Object.type] += Object + AM.resetVariables() + masterPool["[AM.type]"] += AM #ifdef DEBUG_OBJECT_POOL - world << "DEBUG_OBJECT_POOL: returnToPool([Object.type]) [length(masterPool[Object.type])] left." + world << text("DEBUG_OBJECT_POOL: returnToPool([]) [] left.", AM.type, length(masterPool["[AM.type]"])) #endif #undef MAINTAINING_OBJECT_POOL_COUNT @@ -127,20 +125,48 @@ var/list/masterPool = list() #endif /* - * Override this if the object variables needed to reset. + * if you have a variable that needed to be preserve, override this and call .. * - * Example: see, code\game\objects\items\stacks\sheets\glass.dm - * @/obj/item/weapon/shard - * @resetVariables() + * example + * + * /obj/item/resetVariables() + * ..("var1", "var2", "var3") + * + * however, if the object has a child type an it has overridden resetVariables() + * this should be + * + * /obj/item/resetVariables() + * ..("var1", "var2", "var3", args) + * + * /obj/item/weapon/resetVariables() + * ..("var4") */ -/atom/movable - proc/resetVariables() - var/list/exclude = list("loc", "locs", "parent_type", "vars", "verbs", "type") // Read-only or compile-time vars and whatevs. - exclude += args // Explicit var exclusion - var/list/varsCopy = vars - exclude - var/key +/atom/movable/proc/resetVariables() + loc = null - for (key in varsCopy) - vars[key] = initial(vars[key]) + var/list/exclude = global.exclude + args // explicit var exclusion - vars["loc"] = null // Making sure the loc is null not a compile-time var value. + for(var/key in vars) + if(key in exclude) + continue + + vars[key] = initial(vars[key]) + +/proc/isInTypes(atom/Object, types) + var/prototype = Object.type + Object = null + + for (var/type in params2list(types)) + if (ispath(prototype, text2path(type))) + return 1 + + return 0 + + +/obj/machinery/proc/getArea() + var/area/A = loc.loc + + if (A != myArea) + myArea = A + + . = myArea \ No newline at end of file diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 6dac55213d7..a47f261f9c1 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -167,8 +167,6 @@ // The old system would loop through lists for a total of 5000 per function call, in an empty server. // This new system will loop at around 1000 in an empty server. -// SCREW THAT SHIT, we're not recursing. - /proc/get_mobs_in_view(var/R, var/atom/source) // Returns a list of mobs in range of R from source. Used in radio and say code. @@ -180,48 +178,40 @@ var/list/range = hear(R, T) - for(var/mob/M in range) - hear += M + for(var/atom/A in range) + if(ismob(A)) + var/mob/M = A + if(M.client) + hear += M + //world.log << "Start = [M] - [get_turf(M)] - ([M.x], [M.y], [M.z])" + else if(istype(A, /obj/item/device/radio)) + hear += A - var/list/objects = list() + if(isobj(A) || ismob(A)) + hear |= recursive_mob_check(A, hear, 3, 1, 0, 1) - for(var/obj/O in range) //Get a list of objects in hearing range. We'll check to see if any clients have their "eye" set to the object - objects += O - - for(var/client/C in clients) - if(!istype(C) || !C.eye || istype(C.eye, /mob/aiEye)) - continue //I have no idea when this client check would be needed, but if this runtimes people won't hear anything - //So kinda paranoid about runtime avoidance. - if(istype(C.eye, /obj/machinery/camera)) - continue //No microphones in cameras. - - if(C.mob in hear) - continue - - var/list/hear_and_objects = (hear|objects) //Combined these lists here instead of doing the combine 3 more times. - - if(C.eye in hear_and_objects) - hear += C.mob - - else if(C.mob && C.mob.loc in hear_and_objects) - hear += C.mob - else if(C.mob && C.mob.loc.loc in hear_and_objects) - hear += C.mob - else if(C.mob && C.mob.loc.loc.loc in hear_and_objects) - hear += C.mob return hear /proc/get_mobs_in_radio_ranges(var/list/obj/item/device/radio/radios) - //set background = 1 + set background = 1 . = list() // Returns a list of mobs who can hear any of the radios given in @radios var/list/speaker_coverage = list() - for(var/i = 1; i <= radios.len; i++) - var/obj/item/device/radio/R = radios[i] + for(var/obj/item/device/radio/R in radios) if(R) + //Cyborg checks. Receiving message uses a bit of cyborg's charge. + var/obj/item/device/radio/borg/BR = R + if(istype(BR) && BR.myborg) + var/mob/living/silicon/robot/borg = BR.myborg + var/datum/robot_component/CO = borg.get_component("radio") + if(!CO) + continue //No radio component (Shouldn't happen) + if(!borg.is_component_functioning("radio") || !borg.use_power(CO.energy_consumption)) + continue //No power. + var/turf/speaker = get_turf(R) if(speaker) for(var/turf/T in hear(R.canhear_range,speaker)) @@ -239,6 +229,7 @@ . |= M // Since we're already looping through mobs, why bother using |= ? This only slows things down. return . + #define SIGN(X) ((X<0)?-1:1) proc @@ -313,7 +304,8 @@ proc/isInSight(var/atom/A, var/atom/B) return M return null -/proc/get_candidates(be_special_flag=0, afk_bracket=3000, jobban=0, department_jobban=0, override_age=0) +/proc/get_candidates(be_special_flag=0, afk_bracket=3000, override_age=0, override_jobban=0) + var/roletext = get_roletext(be_special_flag) var/list/candidates = list() // Keep looping until we find a non-afk candidate within the time bracket (we limit the bracket to 10 minutes (6000)) while(!candidates.len && afk_bracket < 6000) @@ -321,7 +313,7 @@ proc/isInSight(var/atom/A, var/atom/B) if(G.client != null) if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD)) if(!G.client.is_afk(afk_bracket) && (G.client.prefs.be_special & be_special_flag)) - if(!jobban && !department_jobban || !jobban_isbanned(G, jobban) && !jobban_isbanned(G,department_jobban)) + if(!override_jobban || (!jobban_isbanned(G, roletext) && !jobban_isbanned(G,"Syndicate"))) if(override_age || player_old_enough_antag(G.client,be_special_flag)) candidates += G.client afk_bracket += 600 // Add a minute to the bracket, for every attempt diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index fd062539852..c80127de905 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -25,9 +25,16 @@ var/global/list/joblist = list() //list of all jobstypes, minus borg and AI var/global/list/flag_list = list() //list of flags during Nations gamemode var/global/list/airlocks = list() //list of all airlocks + +var/global/list/alphabet_uppercase = list("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z") //added for Xenoarchaeology, might be useful for other stuff + +var/global/list/aibots = list() // AI controlled bots +var/global/list/table_recipes = list() //list of all table craft recipes + //Languages/species/whitelist. var/global/list/all_species[0] var/global/list/all_languages[0] +var/global/list/language_keys[0] // Table of say codes for all languages var/global/list/all_nations[0] var/global/list/whitelisted_species = list() @@ -44,7 +51,7 @@ 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", "None") +var/global/list/underwear_m = list("White", "Grey", "Green", "Blue", "Black", "Mankini", "None") var/global/list/underwear_f = list("Red", "White", "Yellow", "Blue", "Black", "Thong", "None") var/global/list/underwear_list = underwear_m + underwear_f //undershirt @@ -114,6 +121,13 @@ var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Al var/datum/language/L = new T all_languages[L.name] = L + for (var/language_name in all_languages) + var/datum/language/L = all_languages[language_name] + if(!(L.flags & NONGLOBAL)) + language_keys[":[lowertext(L.key)]"] = L + language_keys[".[lowertext(L.key)]"] = L + language_keys["#[lowertext(L.key)]"] = L + var/rkey = 0 paths = typesof(/datum/species)-/datum/species for(var/T in paths) @@ -124,6 +138,8 @@ var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Al if(S.flags & IS_WHITELISTED) whitelisted_species += S.name + + init_subtypes(/datum/table_recipe, table_recipes) return 1 diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm index 10ab63c9259..2883c5ca5df 100644 --- a/code/__HELPERS/lists.dm +++ b/code/__HELPERS/lists.dm @@ -207,6 +207,7 @@ proc/listclearnulls(list/list) //Mergsort: does the actual sorting and returns the results back to sortAtom /proc/mergeAtoms(var/list/atom/L, var/list/atom/R, var/order = 1) + if(!L || !R) return 0 var/Li=1 var/Ri=1 var/list/result = new() @@ -393,7 +394,187 @@ proc/listclearnulls(list/list) //world.log << " output: [out.len]" return reverselist(out) -/proc/find_record(field, value, list/L) - for(var/datum/data/record/R in L) - if(R.fields[field] == value) - return R \ No newline at end of file +/proc/dd_sortedObjectList(var/list/L, var/cache=list()) + if(L.len < 2) + return L + var/middle = L.len / 2 + 1 // Copy is first,second-1 + return dd_mergeObjectList(dd_sortedObjectList(L.Copy(0,middle), cache), dd_sortedObjectList(L.Copy(middle), cache), cache) //second parameter null = to end of list + +/proc/dd_mergeObjectList(var/list/L, var/list/R, var/list/cache) + var/Li=1 + var/Ri=1 + var/list/result = new() + while(Li <= L.len && Ri <= R.len) + var/LLi = L[Li] + var/RRi = R[Ri] + var/LLiV = cache[LLi] + var/RRiV = cache[RRi] + if(!LLiV) + LLiV = LLi:dd_SortValue() + cache[LLi] = LLiV + if(!RRiV) + RRiV = RRi:dd_SortValue() + cache[RRi] = RRiV + if(LLiV < RRiV) + result += L[Li++] + else + result += R[Ri++] + + if(Li <= L.len) + return (result + L.Copy(Li, 0)) + return (result + R.Copy(Ri, 0)) + +// Insert an object into a sorted list, preserving sortedness +/proc/dd_insertObjectList(var/list/L, var/O) + var/min = 1 + var/max = L.len + var/Oval = O:dd_SortValue() + + while(1) + var/mid = min+round((max-min)/2) + + if(mid == max) + L.Insert(mid, O) + return + + var/Lmid = L[mid] + var/midval = Lmid:dd_SortValue() + if(Oval == midval) + L.Insert(mid, O) + return + else if(Oval < midval) + max = mid + else + min = mid+1 + +/* +proc/dd_sortedObjectList(list/incoming) + /* + Use binary search to order by dd_SortValue(). + This works by going to the half-point of the list, seeing if the node in + question is higher or lower cost, then going halfway up or down the list + and checking again. This is a very fast way to sort an item into a list. + */ + var/list/sorted_list = new() + var/low_index + var/high_index + var/insert_index + var/midway_calc + var/current_index + var/current_item + var/current_item_value + var/current_sort_object_value + var/list/list_bottom + + var/current_sort_object + for (current_sort_object in incoming) + low_index = 1 + high_index = sorted_list.len + while (low_index <= high_index) + // Figure out the midpoint, rounding up for fractions. (BYOND rounds down, so add 1 if necessary.) + midway_calc = (low_index + high_index) / 2 + current_index = round(midway_calc) + if (midway_calc > current_index) + current_index++ + current_item = sorted_list[current_index] + + current_item_value = current_item:dd_SortValue() + current_sort_object_value = current_sort_object:dd_SortValue() + if (current_sort_object_value < current_item_value) + high_index = current_index - 1 + else if (current_sort_object_value > current_item_value) + low_index = current_index + 1 + else + // current_sort_object == current_item + low_index = current_index + break + + // Insert before low_index. + insert_index = low_index + + // Special case adding to end of list. + if (insert_index > sorted_list.len) + sorted_list += current_sort_object + continue + + // Because BYOND lists don't support insert, have to do it by: + // 1) taking out bottom of list, 2) adding item, 3) putting back bottom of list. + list_bottom = sorted_list.Copy(insert_index) + sorted_list.Cut(insert_index) + sorted_list += current_sort_object + sorted_list += list_bottom + return sorted_list +*/ + +proc/dd_sortedtextlist(list/incoming, case_sensitive = 0) + // Returns a new list with the text values sorted. + // Use binary search to order by sortValue. + // This works by going to the half-point of the list, seeing if the node in question is higher or lower cost, + // then going halfway up or down the list and checking again. + // This is a very fast way to sort an item into a list. + var/list/sorted_text = new() + var/low_index + var/high_index + var/insert_index + var/midway_calc + var/current_index + var/current_item + var/list/list_bottom + var/sort_result + + var/current_sort_text + for (current_sort_text in incoming) + low_index = 1 + high_index = sorted_text.len + while (low_index <= high_index) + // Figure out the midpoint, rounding up for fractions. (BYOND rounds down, so add 1 if necessary.) + midway_calc = (low_index + high_index) / 2 + current_index = round(midway_calc) + if (midway_calc > current_index) + current_index++ + current_item = sorted_text[current_index] + + if (case_sensitive) + sort_result = sorttextEx(current_sort_text, current_item) + else + sort_result = sorttext(current_sort_text, current_item) + + switch(sort_result) + if (1) + high_index = current_index - 1 // current_sort_text < current_item + if (-1) + low_index = current_index + 1 // current_sort_text > current_item + if (0) + low_index = current_index // current_sort_text == current_item + break + + // Insert before low_index. + insert_index = low_index + + // Special case adding to end of list. + if (insert_index > sorted_text.len) + sorted_text += current_sort_text + continue + + // Because BYOND lists don't support insert, have to do it by: + // 1) taking out bottom of list, 2) adding item, 3) putting back bottom of list. + list_bottom = sorted_text.Copy(insert_index) + sorted_text.Cut(insert_index) + sorted_text += current_sort_text + sorted_text += list_bottom + return sorted_text + + +proc/dd_sortedTextList(list/incoming) + var/case_sensitive = 1 + return dd_sortedtextlist(incoming, case_sensitive) + + +datum/proc/dd_SortValue() + return "[src]" + +/obj/machinery/dd_SortValue() + return "[sanitize(name)]" + +/obj/machinery/camera/dd_SortValue() + return "[c_tag]" \ No newline at end of file diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index a790124c152..81ed859a7e5 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -49,15 +49,19 @@ proc/random_facial_hair_style(gender, species = "Human") return f_style -proc/random_name(gender, speciesName = "Human") - var/datum/species/S = all_species[speciesName] - if(S) - return S.makeName(gender) - else - if(gender==FEMALE) +proc/random_name(gender, species = "Human") + + var/datum/species/current_species + if(species) + current_species = all_species[species] + + if(!current_species || current_species.name == "Human") + if(gender==FEMALE) return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names)) - else - return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names)) + else + return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names)) + else + return current_species.get_random_name(gender) proc/random_skin_tone() switch(pick(60;"caucasian", 15;"afroamerican", 10;"african", 10;"latino", 5;"albino")) @@ -128,6 +132,8 @@ Proc for attack log creation, because really why not proc/add_logs(mob/target, mob/user, what_done, var/object=null, var/addition=null) var/list/ignore=list("shaked","CPRed","grabbed","punched") + if(!user) + return if(ismob(user)) user.attack_log += text("\[[time_stamp()]\] Has [what_done] [target.name][ismob(target) ? "([target.ckey])" : ""][object ? " with [object]" : " "][addition]") if(ismob(target)) diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 1553550e362..c6cd633398b 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -34,12 +34,9 @@ return t //Removes a few problematic characters -/proc/sanitize_simple(var/t,var/list/repl_chars = list("\n"="#","\t"="#","�"="�")) +/proc/sanitize_simple(var/t,var/list/repl_chars = list("\n"="#","\t"="#")) for(var/char in repl_chars) - var/index = findtext(t, char) - while(index) - t = copytext(t, 1, index) + repl_chars[char] + copytext(t, index+1) - index = findtext(t, char) + replacetext(t, char, repl_chars[char]) return t /proc/readd_quotes(var/t) @@ -82,7 +79,7 @@ // Used to get a sanitized input. /proc/stripped_input(var/mob/user, var/message = "", var/title = "", var/default = "", var/max_length=MAX_MESSAGE_LEN) var/name = input(user, message, title, default) - return strip_html_simple(name, max_length) + return strip_html_properly(name, max_length) //Filters out undesirable characters from names /proc/reject_bad_name(var/t_in, var/allow_numbers=0, var/max_length=MAX_NAME_LEN) @@ -311,4 +308,35 @@ proc/checkhtml(var/t) var/new_text = "" for(var/i = length(text); i > 0; i--) new_text += copytext(text, i, i+1) - return new_text + return new_text + +//This proc strips html properly, but it's not lazy like the other procs. +//This means that it doesn't just remove < and > and call it a day. +//Also limit the size of the input, if specified. +/proc/strip_html_properly(var/input, var/max_length = MAX_MESSAGE_LEN) + if(!input) + return + var/opentag = 1 //These store the position of < and > respectively. + var/closetag = 1 + while(1) + opentag = findtext(input, "<") + closetag = findtext(input, ">") + if(closetag && opentag) + if(closetag < opentag) + input = copytext(input, (closetag + 1)) + else + input = copytext(input, 1, opentag) + copytext(input, (closetag + 1)) + else if(closetag || opentag) + if(opentag) + input = copytext(input, 1, opentag) + else + input = copytext(input, (closetag + 1)) + else + break + if(max_length) + input = copytext(input,1,max_length) + return sanitize(input) + +/proc/trim_strip_html_properly(var/input, var/max_length = MAX_MESSAGE_LEN) + return trim(strip_html_properly(input, max_length)) + \ No newline at end of file diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index c26d2e8d7b8..634697b8e44 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -227,7 +227,7 @@ proc/tg_text2list(text, glue=",", assocglue=";") . += copytext(text, last_found, found) last_found = found + delim_len while(found) - + /proc/text2numlist(text, delimiter="\n") var/list/num_list = list() for(var/x in text2list(text, delimiter)) @@ -347,6 +347,7 @@ proc/tg_text2list(text, glue=",", assocglue=";") if(rights & R_SOUNDS) . += "[seperator]+SOUND" if(rights & R_SPAWN) . += "[seperator]+SPAWN" if(rights & R_MOD) . += "[seperator]+MODERATOR" + if(rights & R_MENTOR) . += "[seperator]+MENTOR" return . /proc/ui_style2icon(ui_style) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index ac841e220df..db7e4dc3ecb 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -411,13 +411,7 @@ Turf and target are seperate in case you want to teleport some distance from a t //world << "[newname] is the AI!" //world << sound('sound/AI/newAI.ogg') // Set eyeobj name - if(A.eyeobj) - A.eyeobj.name = "[newname] (AI Eye)" - - // Set ai pda name - if(A.aiPDA) - A.aiPDA.owner = newname - A.aiPDA.name = newname + " (" + A.aiPDA.ownjob + ")" + A.SetName(newname) fully_replace_character_name(oldname,newname) @@ -1391,6 +1385,7 @@ proc/is_hot(obj/item/W as obj) //Returns 1 if the given item is capable of popping things like balloons, inflatable barriers, or cutting police tape. /proc/can_puncture(obj/item/W as obj) // For the record, WHAT THE HELL IS THIS METHOD OF DOING IT? + if(!istype(W)) return 0 if(!W) return 0 if(W.sharp) return 1 return ( \ diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index 5e65bc57536..96709e751f7 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -15,7 +15,6 @@ return if(control_disabled || stat) return - next_move = world.time + 9 if(ismob(A)) ai_actual_track(A) @@ -60,7 +59,6 @@ if(world.time <= next_move) return - next_move = world.time + 9 if(aiCamera.in_camera_mode) aiCamera.camera_mode_off() @@ -161,8 +159,7 @@ Topic("breaker=1", list("breaker"="1"), 0) // 0 meaning no window (consistency! wait...) /obj/machinery/turretid/AICtrlClick() //turns off/on Turrets - src.enabled = !src.enabled - src.updateTurrets() + Topic(src, list("src"= "\ref[src]", "command"="enable", "value"="[!enabled]"), 1) // 1 meaning no window (consistency!) /atom/proc/AIAltClick(var/atom/A) AltClick(A) @@ -181,8 +178,7 @@ return /obj/machinery/turretid/AIAltClick() //toggles lethal on turrets - src.lethal = !src.lethal - src.updateTurrets() + Topic(src, list("src"= "\ref[src]", "command"="lethal", "value"="[!lethal]"), 1) // 1 meaning no window (consistency!) /atom/proc/AIMiddleClick() return diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index bb288fc7d48..da2013e2e58 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -65,7 +65,7 @@ if(stat || paralysis || stunned || weakened) return - face_atom(A) // change direction to face what you clicked on + face_atom(A) if(next_move > world.time) // in the year 2000... return @@ -77,6 +77,7 @@ return M.click_action(A,src) if(restrained()) + changeNext_move(CLICK_CD_HANDCUFFED) //Doing shit in cuffs shall be vey slow RestrainedClickOn(A) return @@ -87,56 +88,45 @@ var/obj/item/W = get_active_hand() if(W == A) - next_move = world.time + 6 - if(W.flags&USEDELAY) - next_move += 5 W.attack_self(src) if(hand) update_inv_l_hand(0) else update_inv_r_hand(0) - 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)) - - // faster access to objects already on you - if(A in contents) - next_move = world.time + 6 // on your person - else - next_move = world.time + 8 // in a box/bag or in your square - + // 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)) // No adjacency needed if(W) - if(W.flags&USEDELAY) - next_move += 5 - var/resolved = A.attackby(W,src) if(!resolved && A && W) W.afterattack(A,src,1,params) // 1 indicates adjacency else - UnarmedAttack(A) + if(ismob(A)) + changeNext_move(CLICK_CD_MELEE) + UnarmedAttack(A, 1) + return if(!isturf(loc)) // This is going to stop you from telekinesing from inside a closet, but I don't shed many tears for that 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))) - next_move = world.time + 10 - + sdepth = A.storage_depth_turf() + if(isturf(A) || isturf(A.loc) || (sdepth != -1 && sdepth <= 1)) if(A.Adjacent(src)) // see adjacent.dm if(W) - if(W.flags&USEDELAY) - next_move += 5 - - // Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example) - var/resolved = A.attackby(W,src) + // Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example, params) + var/resolved = A.attackby(W,src,params) if(!resolved && A && W) W.afterattack(A,src,1,params) // 1: clicking something Adjacent else + if(ismob(A)) + changeNext_move(CLICK_CD_MELEE) UnarmedAttack(A, 1) + return else // non-adjacent click if(W) @@ -146,10 +136,12 @@ return +/mob/proc/changeNext_move(num) + next_move = world.time + num + // Default behavior: ignore double clicks, consider them normal clicks instead /mob/proc/DblClickOn(var/atom/A, var/params) - ClickOn(A,params) - + return /* Translates into attack_hand, etc. @@ -162,6 +154,8 @@ in human click code to allow glove touches only at melee range. */ /mob/proc/UnarmedAttack(var/atom/A, var/proximity_flag) + if(ismob(A)) + changeNext_move(CLICK_CD_MELEE) return /* @@ -176,22 +170,12 @@ if(ishuman(src) && (istype(src:gloves, /obj/item/clothing/gloves/yellow/power)) && a_intent == "harm") PowerGlove(A) if(!mutations.len) return - if((M_LASER in mutations) && a_intent == "harm") + if((LASER in mutations) && a_intent == "harm") LaserEyes(A) // moved into a proc below return - else if(M_TK in mutations) - switch(get_dist(src,A)) - if(0) - ; - if(1 to 5) // not adjacent may mean blocked by window - next_move += 2 - if(5 to 7) - next_move += 5 - if(8 to tk_maxrange) - next_move += 10 - else - return - A.attack_tk(src) + else + if(TK in mutations) + A.attack_tk(src) /* Restrained ClickOn @@ -209,6 +193,13 @@ A.point() return +/mob/living/carbon/MiddleClickOn(var/atom/A) + if(!src.stat && src.mind && src.mind.changeling && src.mind.changeling.chosen_sting && (istype(A, /mob/living/carbon)) && (A != src)) + next_click = world.time + 5 + mind.changeling.chosen_sting.try_to_sting(src, A) + else + A.point() + // In case of use break glass /* /atom/proc/MiddleClick(var/mob/M as mob) @@ -251,6 +242,13 @@ A.AltClick(src) return +/mob/living/carbon/AltClickOn(var/atom/A) + if(!src.stat && src.mind && src.mind.changeling && src.mind.changeling.chosen_sting && (istype(A, /mob/living/carbon)) && (A != src)) + next_click = world.time + 5 + mind.changeling.chosen_sting.try_to_sting(src, A) + else + ..() + /atom/proc/AltClick(var/mob/user) var/turf/T = get_turf(src) if(T && user.TurfAdjacent(T)) @@ -273,16 +271,16 @@ return /atom/proc/CtrlShiftClick(var/mob/user) - return + return /mob/proc/AltShiftClickOn(var/atom/A) A.AltShiftClick(src) return /atom/proc/AltShiftClick(var/mob/user) - return - - + return + + /* Misc helpers @@ -293,7 +291,7 @@ return /mob/living/LaserEyes(atom/A) - next_move = world.time + 6 + changeNext_move(CLICK_CD_RANGE) var/turf/T = get_turf(src) var/turf/U = get_turf(A) @@ -346,21 +344,9 @@ if(available >= 5000000) L.damage = 205 if(L.damage >= 200) - apply_damage(15, BURN, (hand ? "l_hand" : "r_hand")) - //usr:Stun(15) - //usr:Weaken(15) - //if(usr:status_flags & CANSTUN) // stun is usually associated with stutter - // usr:stuttering += 20 time = 200 - src << "[G] overload from the massive current shocking you in the process!" else if(L.damage >= 100) - apply_damage(5, BURN, (hand ? "l_hand" : "r_hand")) - //usr:Stun(10) - //usr:Weaken(10) - //if(usr:status_flags & CANSTUN) // stun is usually associated with stutter - // usr:stuttering += 10 time = 150 - src << "[G] overload from the massive current shocking you in the process!" var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(5, 1, src) s.start() diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index 4e20ef9ec32..6d497cff462 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -72,21 +72,13 @@ return if(W == A) - next_move = world.time + 8 - if(W.flags&USEDELAY) - next_move += 5 - W.attack_self(src) return // cyborgs are prohibited from using storage items so we can I think safely remove (A.loc in contents) if(A == loc || (A in loc) || (A in contents)) // No adjacency checks - next_move = world.time + 8 - if(W.flags&USEDELAY) - next_move += 5 - - var/resolved = A.attackby(W,src) + var/resolved = A.attackby(W,src,params, params) if(!resolved && A && W) W.afterattack(A,src,1,params) return @@ -97,16 +89,11 @@ // cyborgs are prohibited from using storage items so we can I think safely remove (A.loc && isturf(A.loc.loc)) if(isturf(A) || isturf(A.loc)) if(A.Adjacent(src)) // see adjacent.dm - next_move = world.time + 10 - if(W.flags&USEDELAY) - next_move += 5 - - var/resolved = A.attackby(W, src) + var/resolved = A.attackby(W, src, params, params) if(!resolved && A && W) W.afterattack(A, src, 1, params) return else - next_move = world.time + 10 W.afterattack(A, src, 0, params) return return diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm index 98b99d0a1d3..17616801b76 100644 --- a/code/_onclick/hud/_defines.dm +++ b/code/_onclick/hud/_defines.dm @@ -114,6 +114,11 @@ #define ui_borg_health "16:28,6:13" //borgs have the health display where humans have the pressure damage indicator. #define ui_alien_health "16:28,6:13" //aliens have the health display where humans have the pressure damage indicator. +#define ui_construct_health "16:00,8:17" //same height as humans, hugging the right border +#define ui_construct_purge "16:00,6:15" +#define ui_construct_fire "15:16,8:13" //above health, slightly to the left +#define ui_construct_pull "16:28,2:10" //above the zone_sel icon + //Pop-up inventory #define ui_shoes "2:8,1:5" diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 20e50d9472c..9e64de0697b 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -190,6 +190,8 @@ datum/hud/New(mob/owner) ai_hud() else if(isrobot(mymob)) robot_hud() + else if(iscorgi(mymob)) + corgi_hud() else if(isobserver(mymob)) ghost_hud() else if(isovermind(mymob)) diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index e6839dcfbaf..2bbe14bea42 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -507,6 +507,7 @@ /mob/living/carbon/human/update_action_buttons() var/num = 1 + var/list/to_update = list() if(!hud_used) return if(!client) return @@ -519,37 +520,44 @@ for(var/obj/item/I in src) if(istype(I,/obj/item/clothing/under)) var/obj/item/clothing/under/U = I - if(U.hastie) - I = U.hastie + if(U.accessories) + for(var/obj/item/clothing/accessory/AC in U.accessories) + if(AC.icon_action_button) + to_update += AC + continue if(I.icon_action_button) - var/obj/screen/item_action/A = new(hud_used) - - //A.icon = 'icons/mob/screen1_action.dmi' - //A.icon_state = I.icon_action_button - A.icon = ui_style2icon(client.prefs.UI_style) - A.icon_state = "template" - var/image/img = image(I.icon, A, I.icon_state) - img.pixel_x = 0 - img.pixel_y = 0 - A.overlays += img + to_update += I + continue + + for(var/obj/item/I in to_update) + var/obj/screen/item_action/A = new(hud_used) + + //A.icon = 'icons/mob/screen1_action.dmi' + //A.icon_state = I.icon_action_button + A.icon = ui_style2icon(client.prefs.UI_style) + A.icon_state = "template" + var/image/img = image(I.icon, A, I.icon_state) + img.pixel_x = 0 + img.pixel_y = 0 + A.overlays += img - if(I.action_button_name) - A.name = I.action_button_name - else - A.name = "Use [I.name]" - A.owner = I - hud_used.item_action_list += A - switch(num) - if(1) - A.screen_loc = ui_action_slot1 - if(2) - A.screen_loc = ui_action_slot2 - if(3) - A.screen_loc = ui_action_slot3 - if(4) - A.screen_loc = ui_action_slot4 - if(5) - A.screen_loc = ui_action_slot5 - break //5 slots available, so no more can be added. - num++ + if(I.action_button_name) + A.name = I.action_button_name + else + A.name = "Use [I.name]" + A.owner = I + hud_used.item_action_list += A + switch(num) + if(1) + A.screen_loc = ui_action_slot1 + if(2) + A.screen_loc = ui_action_slot2 + if(3) + A.screen_loc = ui_action_slot3 + if(4) + A.screen_loc = ui_action_slot4 + if(5) + A.screen_loc = ui_action_slot5 + break //5 slots available, so no more can be added. + num++ src.client.screen += src.hud_used.item_action_list \ No newline at end of file diff --git a/code/_onclick/hud/other_mobs.dm b/code/_onclick/hud/other_mobs.dm index 2cb7cd15b41..f84cfd6c232 100644 --- a/code/_onclick/hud/other_mobs.dm +++ b/code/_onclick/hud/other_mobs.dm @@ -5,6 +5,41 @@ /datum/hud/proc/ghost_hud() return +/datum/hud/proc/corgi_hud(u) + mymob.fire = new /obj/screen() + mymob.fire.icon = 'icons/mob/screen1_corgi.dmi' + mymob.fire.icon_state = "fire0" + mymob.fire.name = "fire" + mymob.fire.screen_loc = ui_fire + + mymob.healths = new /obj/screen() + mymob.healths.icon = 'icons/mob/screen1_corgi.dmi' + mymob.healths.icon_state = "health0" + mymob.healths.name = "health" + mymob.healths.screen_loc = ui_health + + mymob.pullin = new /obj/screen() + mymob.pullin.icon = 'icons/mob/screen1_corgi.dmi' + mymob.pullin.icon_state = "pull0" + mymob.pullin.name = "pull" + mymob.pullin.screen_loc = ui_construct_pull + + mymob.oxygen = new /obj/screen() + mymob.oxygen.icon = 'icons/mob/screen1_corgi.dmi' + mymob.oxygen.icon_state = "oxy0" + mymob.oxygen.name = "oxygen" + mymob.oxygen.screen_loc = ui_oxygen + + mymob.toxin = new /obj/screen() + mymob.toxin.icon = 'icons/mob/screen1_corgi.dmi' + mymob.toxin.icon_state = "tox0" + mymob.toxin.name = "toxin" + mymob.toxin.screen_loc = ui_toxin + + mymob.client.screen = null + + mymob.client.screen += list(mymob.fire, mymob.healths, mymob.pullin, mymob.oxygen, mymob.toxin) + /datum/hud/proc/brain_hud(ui_style = 'icons/mob/screen1_Midnight.dmi') mymob.blind = new /obj/screen() mymob.blind.icon = 'icons/mob/screen1_full.dmi' diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index efa433476d6..7406307c632 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 /obj/screen/power_action @@ -55,7 +52,6 @@ return 1 if(usr.next_move >= world.time) return - usr.next_move = world.time + 6 if(usr.stat || usr.restrained() || usr.stunned || usr.lying) return 1 @@ -90,7 +86,7 @@ /obj/screen/storage name = "storage" -/obj/screen/storage/Click() +/obj/screen/storage/Click(location, control, params) if(world.time <= usr.next_move) return 1 if(usr.stat || usr.paralysis || usr.stunned || usr.weakened) @@ -100,8 +96,7 @@ if(master) var/obj/item/I = usr.get_active_hand() if(I) - master.attackby(I, usr) - usr.next_move = world.time+2 + master.attackby(I, usr, params, params) return 1 /obj/screen/gun @@ -281,6 +276,9 @@ if(!istype(C.wear_mask, /obj/item/clothing/mask)) C << "You are not wearing a mask." return 1 + if(C.wear_mask.mask_adjusted) + C << "Put your mask on first." + return 1 else var/list/nicename = null var/list/tankcheck = null @@ -409,7 +407,7 @@ if("Toggle Sensor Augmentation") if(isrobot(usr)) var/mob/living/silicon/robot/R = usr - R.control_hud() + R.sensor_mode() if("module1") if(istype(usr, /mob/living/silicon/robot)) @@ -506,8 +504,7 @@ if("Crew Monitoring") if(isAI(usr)) var/mob/living/silicon/ai/AI = usr - var/obj/machinery/computer/crew/C = locate(/obj/machinery/computer/crew) - C.attack_ai(AI) + AI.nano_crew_monitor() if("Show Crew Manifest") if(isAI(usr)) @@ -557,7 +554,7 @@ if("Set Sensor Augmentation") if(isAI(usr)) var/mob/living/silicon/ai/AI = usr - AI.control_hud() + AI.sensor_mode() // Alien if("night vision") @@ -587,12 +584,10 @@ if(iscarbon(usr)) var/mob/living/carbon/C = usr C.activate_hand("r") - usr.next_move = world.time+2 if("l_hand") if(iscarbon(usr)) var/mob/living/carbon/C = usr C.activate_hand("l") - usr.next_move = world.time+2 if("swap") usr:swap_hand() if("hand") @@ -601,5 +596,4 @@ if(usr.attack_ui(slot_id)) usr.update_inv_l_hand(0) usr.update_inv_r_hand(0) - usr.next_move = world.time+6 return 1 diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 07fb74b8359..35e19f568a1 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -4,13 +4,16 @@ return // No comment -/atom/proc/attackby(obj/item/W, mob/user) +/atom/proc/attackby(obj/item/W, mob/living/user, params) return -/atom/movable/attackby(obj/item/W, mob/user) +/atom/movable/attackby(obj/item/W, mob/living/user, params) + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) if(!(W.flags&NOBLUDGEON)) visible_message("[src] has been hit by [user] with [W].") -/mob/living/attackby(obj/item/I, mob/user) +/mob/living/attackby(obj/item/I, mob/user, params) + user.changeNext_move(CLICK_CD_MELEE) if(istype(I) && ismob(user)) I.attack(src, user) @@ -50,8 +53,6 @@ ///////////////////////// var/power = force - if(M_HULK in user.mutations) - power *= 2 if(!istype(M, /mob/living/carbon/human)) if(istype(M, /mob/living/carbon/slime)) @@ -128,6 +129,7 @@ var/showname = "." if(user) showname = " by [user]." + user.do_attack_animation(src) if(!(user in viewers(M, null))) showname = "." @@ -159,7 +161,7 @@ if (istype(location, /turf/simulated)) location:add_blood_floor(M) if("fire") - if (!(M_RESIST_COLD in M.mutations)) + if (!(RESIST_COLD in M.mutations)) M.take_organ_damage(0, power) M << "Aargh it burns!" M.updatehealth() diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 1fd31a5bd18..6d3842734f6 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -19,8 +19,8 @@ if(client.buildmode) build_click(src, client.buildmode, params, A) return - if(world.time <= next_move) return - next_move = world.time + 8 + if(world.time <= next_move) + return var/list/modifiers = params2list(params) if(modifiers["shift"]) @@ -57,17 +57,18 @@ A.examine() /atom/proc/attack_ghost(mob/user as mob) - src.examine() + return // --------------------------------------- // And here are some good things for free: // Now you can click through portals, wormholes, gateways, and teleporters while observing. -Sayu /obj/machinery/teleport/hub/attack_ghost(mob/user as mob) - var/atom/l = loc - var/obj/machinery/computer/teleporter/com = locate(/obj/machinery/computer/teleporter, locate(l.x - 2, l.y, l.z)) - if(com.locked) - user.loc = get_turf(com.locked) + var/obj/machinery/teleport/station/S = power_station + if(S) + var/obj/machinery/computer/teleporter/com = S.teleporter_console + if(com && com.target) + user.loc = get_turf(com.target) /obj/effect/portal/attack_ghost(mob/user as mob) if(target) diff --git a/code/_onclick/oldcode.dm b/code/_onclick/oldcode.dm index f81c3f9e37f..954d2eac3fd 100644 --- a/code/_onclick/oldcode.dm +++ b/code/_onclick/oldcode.dm @@ -270,7 +270,7 @@ // ------- YOU HAVE AN ITEM IN YOUR HAND - HANDLE ATTACKBY AND AFTERATTACK ------- var/ignoreAA = 0 //Ignore afterattack(). Surgery uses this. if (t5) - ignoreAA = src.attackby(W, usr) + ignoreAA = src.attackby(W, usr, params) if (W && !ignoreAA) W.afterattack(src, usr, (t5 ? 1 : 0), params) @@ -326,7 +326,7 @@ // ------- YOU ARE NOT RESTRAINED ------- if ((W && !( istype(src, /obj/screen) ))) // ------- IT SHOULD NEVER GET TO HERE, DUE TO THE ISTYPE(SRC, /OBJ/SCREEN) FROM PREVIOUS IF-S - I TESTED IT WITH A DEBUG OUTPUT AND I COULDN'T GET THIST TO SHOW UP. ------- - src.attackby(W, usr) + src.attackby(W, usr, params) if (W) W.afterattack(src, usr,, params) else @@ -347,8 +347,8 @@ src.hand_al(usr, usr.hand) else // ------- YOU ARE CLICKING ON AN OBJECT THAT'S INACCESSIBLE TO YOU AND IS NOT YOUR HUD ------- - if((M_LASER in usr:mutations) && usr:a_intent == "harm" && world.time >= usr.next_move) - // ------- YOU HAVE THE M_LASER MUTATION, YOUR INTENT SET TO HURT AND IT'S BEEN MORE THAN A DECISECOND SINCE YOU LAS TATTACKED ------- + if((LASER in usr:mutations) && usr:a_intent == "harm" && world.time >= usr.next_move) + // ------- YOU HAVE THE LASER MUTATION, YOUR INTENT SET TO HURT AND IT'S BEEN MORE THAN A DECISECOND SINCE YOU LAS TATTACKED ------- var/turf/T = get_turf(usr) var/turf/U = get_turf(src) diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 427b286800b..1dd064219a5 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -17,32 +17,26 @@ /atom/proc/attack_hand(mob/user as mob) return -/mob/living/carbon/human/RestrainedClickOn(var/atom/A) +/* +/mob/living/carbon/human/RestrainedClickOn(var/atom/A) -- Handled by carbons return +*/ - +/mob/living/carbon/RestrainedClickOn(var/atom/A) + return 0 // Commented out to prevent overwriting RangedAttack in click.dm ~ Bone White /* /mob/living/carbon/human/RangedAttack(var/atom/A) if(!gloves && !mutations.len) return var/obj/item/clothing/gloves/G = gloves - if((M_LASER in mutations) && a_intent == "harm") + if((LASER in mutations) && a_intent == "harm") LaserEyes(A) // moved into a proc below else if(istype(G) && G.Touch(A,0)) // for magic gloves return - else if(M_TK in mutations) - switch(get_dist(src,A)) - if(1 to 5) // not adjacent may mean blocked by window - next_move += 2 - if(5 to 7) - next_move += 5 - if(8 to 15) - next_move += 10 - if(16 to 128) - return + else if(TK in mutations) A.attack_tk(src) */ @@ -72,8 +66,10 @@ things considerably */ /mob/living/carbon/monkey/RestrainedClickOn(var/atom/A) + if(..()) + return if(a_intent != "harm" || !ismob(A)) return - if(istype(wear_mask, /obj/item/clothing/mask/muzzle)) + if(is_muzzled()) return var/mob/living/carbon/ML = A var/dam_zone = ran_zone(pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")) diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm index 0eadbff6696..46662142fba 100644 --- a/code/_onclick/telekinesis.dm +++ b/code/_onclick/telekinesis.dm @@ -39,13 +39,13 @@ var/const/tk_maxrange = 15 /obj/item/attack_tk(mob/user) if(user.stat || !isturf(loc)) return - if((M_TK in user.mutations) && !user.get_active_hand()) // both should already be true to get here + if((TK in user.mutations) && !user.get_active_hand()) // both should already be true to get here var/obj/item/tk_grab/O = new(src) user.put_in_active_hand(O) O.host = user O.focus_object(src) else - warning("Strange attack_tk(): TK([M_TK in user.mutations]) empty hand([!user.get_active_hand()])") + warning("Strange attack_tk(): TK([TK in user.mutations]) empty hand([!user.get_active_hand()])") return @@ -56,7 +56,7 @@ var/const/tk_maxrange = 15 TK Grab Item (the workhorse of old TK) * If you have not grabbed something, do a normal tk attack - * If you have something, throw it at the target. If it is already adjacent, do a normal attackby() + * If you have something, throw it at the target. If it is already adjacent, do a normal attackby(, params) * If you click what you are holding, or attack_self(), do an attack_self_tk() on it. * Deletes itself if it is ever not in your hand, or if you should have no access to TK. */ @@ -65,7 +65,7 @@ var/const/tk_maxrange = 15 desc = "Magic" icon = 'icons/obj/magic.dmi'//Needs sprites icon_state = "2" - flags = NOBLUDGEON + flags = NOBLUDGEON | ABSTRACT //item_state = null w_class = 10.0 layer = 20 @@ -95,33 +95,24 @@ var/const/tk_maxrange = 15 if(focus) focus.attack_self_tk(user) - afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity)//TODO: go over this + afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity, params)//TODO: go over this if(!target || !user) return if(last_throw+3 > world.time) return if(!host || host != user) del(src) return - if(!(M_TK in host.mutations)) + if(!(TK in host.mutations)) del(src) return if(isobj(target) && !isturf(target.loc)) return var/d = get_dist(user, target) - if(focus) d = max(d,get_dist(user,focus)) // whichever is further - switch(d) - if(0) - ; - if(1 to 5) // not adjacent may mean blocked by window - if(!proximity) - user.next_move += 2 - if(5 to 7) - user.next_move += 5 - if(8 to tk_maxrange) - user.next_move += 10 - else - user << "\blue Your mind won't reach that far." - return + if(focus) + d = max(d,get_dist(user,focus)) // whichever is further + if(d > tk_maxrange) + user << "Your mind won't reach that far." + return if(!focus) focus_object(target, user) @@ -134,7 +125,7 @@ var/const/tk_maxrange = 15 if(!istype(target, /turf) && istype(focus,/obj/item) && target.Adjacent(focus)) var/obj/item/I = focus - var/resolved = target.attackby(I, user, user:get_organ_target()) + var/resolved = target.attackby(I, user, params) if(!resolved && target && I) I.afterattack(target,user,1) // for splashing with beakers @@ -172,7 +163,7 @@ var/const/tk_maxrange = 15 O.icon_state = "nothing" flick("empdisable",O) spawn(5) - O.delete() + qdel(O) return @@ -198,7 +189,7 @@ var/const/tk_maxrange = 15 //equip_to_slot_or_del(obj/item/W, slot, del_on_fail = 1) /* if(istype(user, /mob/living/carbon)) - if(user:mutations & M_TK && get_dist(source, user) <= 7) + if(user:mutations & TK && get_dist(source, user) <= 7) if(user:get_active_hand()) return 0 var/X = source:x var/Y = source:y diff --git a/code/controllers/ProcessScheduler/.gitignore b/code/controllers/ProcessScheduler/.gitignore new file mode 100644 index 00000000000..5fe19e425bf --- /dev/null +++ b/code/controllers/ProcessScheduler/.gitignore @@ -0,0 +1,6 @@ +/bower_components +/node_modules +/ProcessScheduler.dmb +/ProcessScheduler.int +/ProcessScheduler.rsc +/*.lk diff --git a/code/controllers/ProcessScheduler/LICENSE-AGPL b/code/controllers/ProcessScheduler/LICENSE-AGPL new file mode 100644 index 00000000000..abaa41e8296 --- /dev/null +++ b/code/controllers/ProcessScheduler/LICENSE-AGPL @@ -0,0 +1,212 @@ +GNU AFFERO GENERAL PUBLIC LICENSE + +Version 3, 19 November 2007 + +Copyright © 2007 Free Software Foundation, Inc. +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The GNU Affero General Public License is a free, copyleft license for software and other kinds of works, specifically designed to ensure cooperation with the community in the case of network server software. + +The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, our General Public Licenses are intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. + +Developers that use our General Public Licenses protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License which gives you legal permission to copy, distribute and/or modify the software. + +A secondary benefit of defending all users' freedom is that improvements made in alternate versions of the program, if they receive widespread use, become available for other developers to incorporate. Many developers of free software are heartened and encouraged by the resulting cooperation. However, in the case of software used on network servers, this result may fail to come about. The GNU General Public License permits making a modified version and letting the public access it on a server without ever releasing its source code to the public. + +The GNU Affero General Public License is designed specifically to ensure that, in such cases, the modified source code becomes available to the community. It requires the operator of a network server to provide the source code of the modified version running there to the users of that server. Therefore, public use of a modified version, on a publicly accessible server, gives the public access to the source code of the modified version. + +An older license, called the Affero General Public License and published by Affero, was designed to accomplish similar goals. This is a different license, not a version of the Affero GPL, but Affero has released a new version of the Affero GPL which permits relicensing under this license. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS + +0. Definitions. +"This License" refers to version 3 of the GNU Affero General Public License. + +"Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +"The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. + +To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. + +A "covered work" means either the unmodified Program or a work based on the Program. + +To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. + +1. Source Code. +The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. + +A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +2. Basic Permissions. +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. + +4. Conveying Verbatim Copies. +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. + +5. Conveying Modified Source Versions. +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + +a) The work must carry prominent notices stating that you modified it, and giving a relevant date. +b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". +c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. +d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. + +6. Conveying Non-Source Forms. +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + +a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. +b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. +c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. +d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. +e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +"Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. + +7. Additional Terms. +"Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + +a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or +b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or +c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or +d) Limiting the use for publicity purposes of names of licensors or authors of the material; or +e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or +f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. +All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. + +8. Termination. +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. + +9. Acceptance Not Required for Having Copies. +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. + +10. Automatic Licensing of Downstream Recipients. +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. + +11. Patents. +A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". + +A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. + +12. No Surrender of Others' Freedom. +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. + +13. Remote Network Interaction; Use with the GNU General Public License. +Notwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network (if your version supports such interaction) an opportunity to receive the Corresponding Source of your version by providing access to the Corresponding Source from a network server at no charge, through some standard or customary means of facilitating copying of software. This Corresponding Source shall include the Corresponding Source for any work covered by version 3 of the GNU General Public License that is incorporated pursuant to the following paragraph. + +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the work with which it is combined will remain governed by version 3 of the GNU General Public License. + +14. Revised Versions of this License. +The Free Software Foundation may publish revised and/or new versions of the GNU Affero General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU Affero General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU Affero General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU Affero General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. + +15. Disclaimer of Warranty. +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. Limitation of Liability. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +17. Interpretation of Sections 15 and 16. +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +Also add information on how to contact you by electronic and paper mail. + +If your software can interact with users remotely through a computer network, you should also make sure that it provides a way for users to get its source. For example, if your program is a web application, its interface could display a "Source" link that leads users to an archive of the code. There are many ways you could offer source, and different solutions will be better for different programs; see section 13 for the specific requirements. + +You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/LICENSE-CC-BY-NC b/code/controllers/ProcessScheduler/LICENSE-CC-BY-NC new file mode 100644 index 00000000000..d0955f424af --- /dev/null +++ b/code/controllers/ProcessScheduler/LICENSE-CC-BY-NC @@ -0,0 +1 @@ +This work is licensed under the Creative Commons Attribution-NonCommercial 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/ProcessScheduler.dme b/code/controllers/ProcessScheduler/ProcessScheduler.dme new file mode 100644 index 00000000000..bf17734cc28 --- /dev/null +++ b/code/controllers/ProcessScheduler/ProcessScheduler.dme @@ -0,0 +1,32 @@ +// DM Environment file for ProcessScheduler.dme. +// All manual changes should be made outside the BEGIN_ and END_ blocks. +// New source code should be placed in .dm files: choose File/New --> Code File. + +// BEGIN_INTERNALS +// END_INTERNALS + +// BEGIN_FILE_DIR +#define FILE_DIR . +// END_FILE_DIR + +// BEGIN_PREFERENCES +// END_PREFERENCES + +// BEGIN_INCLUDE +#include "core\_define.dm" +#include "core\_stubs.dm" +#include "core\process.dm" +#include "core\processScheduler.dm" +#include "core\updateQueue.dm" +#include "core\updateQueueWorker.dm" +#include "test\processSchedulerView.dm" +#include "test\testDyingUpdateQueueProcess.dm" +#include "test\testHarness.dm" +#include "test\testHungProcess.dm" +#include "test\testNiceProcess.dm" +#include "test\testSlowProcess.dm" +#include "test\testUpdateQueue.dm" +#include "test\testUpdateQueueProcess.dm" +#include "test\testZombieProcess.dm" +// END_INCLUDE + diff --git a/code/controllers/ProcessScheduler/README.md b/code/controllers/ProcessScheduler/README.md new file mode 100644 index 00000000000..610800ba374 --- /dev/null +++ b/code/controllers/ProcessScheduler/README.md @@ -0,0 +1,86 @@ +ProcessScheduler +================ +A Goonstation release, maintained by Volundr + +##SUMMARY + +This is a mostly self-contained, fairly well-documented implementation of the main loop process architecture in use in Goonstation. + +##LICENSE + +This work is released under the following licenses. + +[![Creative Commons License](https://licensebuttons.net/l/by-nc/4.0/80x15.png)](http://creativecommons.org/licenses/by-nc/4.0/) + +This work is licensed under the Creative Commons Attribution-NonCommercial 4.0 International License. The complete text of this license is included in the file LICENSE-CC-BY-NC. + + +[![Affero GPL Version 3](http://www.gnu.org/graphics/agplv3-88x31.png)](http://www.gnu.org/licenses/agpl-3.0.html) + +This work is licensed under the Affero General Public License 3.0. The complete text of the license is included in the file LICENSE-AGPL. + +##INSTALLATION + +To integrate the process scheduler to your codebase, you will not need anything except the contents of the core/ folder. The rest of the project is simply for testing and to provide an example for the process scheduler code. + +### Test project setup +To compile and run the test project, you will require: + +- node.js +- BYOND + +Clone the repository to a path of your choosing, then change directory to it and execute: + +``` +npm install -g +bower install -g +``` + +Then you can either compile with DM or open the DM environment in DreamMaker and compile/run from there. + +##USAGE + +###BASICS +To use the process scheduler in your SS13 codebase, you'll need: + +- core/_defines.dm +- core/_stubs.dm +- core/process.dm +- core/processScheduler.dm +- core/processScheduler.js +- core/updateQueue.dm +- core/updateQueueWorker.dm + +To integrate, you can copy the contents of _defines.dm into your global defines file. Most ss13 codebases already have the code from _stubs.dm. + +The processScheduler is intended as a replacement for the old master_controller from r4407 and other fork codebases. To implement it, you need only to add the source files to your DM environment, and add the following code into world.New, above where the old master_controller is initialized. + +``` +processScheduler = new +processScheduler.setup() +processScheduler.start() +``` + +The processScheduler will automatically find all subtypes of process, and begin processing them. + +The interface code in test/processSchedulerView.dm is simply an example frontend, and can easily be rebuilt to use other styles, and/or render simple html without using javascript for refreshing the panel and killing processes. + +###DETAILS + +To implement a process, you have two options: + +1. Implement a raw loop-style processor +2. Implement an updateQueue processor + +There are clear examples of both of these paradigms in the code provided. Both styles are valid, but for processes that are just a loop calling an update proc on a bunch of objects, you should use the updateQueue. + +The updateQueue works by spawn(0)'ing your specified update proc, but it only puts one instance in the scheduler at a time. Examine the code for more details. The overall effect of this is that it doesn't block, and it lets update loops work concurrently. It enables a much smoother user experience. + +##Contributing + +I welcome pull requests and issue reports, and will try to merge/fix them as I have time. + +### Licensing for code submitted via PR: + +By submitting a pull request, you agree to release all original code submitted in the pull request under the [MIT License](http://opensource.org/licenses/MIT). You also agree that any code submitted is either your own work, or is public domain or under a equally or less restrictive license than the MIT license, or that you have the express written permission of the authors of the submitted code to submit the pull request. + diff --git a/code/controllers/ProcessScheduler/bower.json b/code/controllers/ProcessScheduler/bower.json new file mode 100644 index 00000000000..9a6be56140d --- /dev/null +++ b/code/controllers/ProcessScheduler/bower.json @@ -0,0 +1,30 @@ +{ + "name": "ProcessScheduler", + "main": "ProcessScheduler.js", + "version": "1.0.0", + "homepage": "https://github.com/goonstation/ProcessScheduler", + "authors": [ + "Volundr " + ], + "description": "BYOND SS13 Process Scheduler", + "keywords": [ + "byond", + "ss13", + "process", + "scheduler" + ], + "license": "CC-BY-NC", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "private": true, + "dependencies": { + "bootstrap2.3.2": "~2.3.2", + "jquery": "1.11.1", + "json2": "*" + } +} diff --git a/code/controllers/ProcessScheduler/core/_define.dm b/code/controllers/ProcessScheduler/core/_define.dm new file mode 100644 index 00000000000..f0165c98708 --- /dev/null +++ b/code/controllers/ProcessScheduler/core/_define.dm @@ -0,0 +1,17 @@ +// Process status defines +#define PROCESS_STATUS_IDLE 1 +#define PROCESS_STATUS_QUEUED 2 +#define PROCESS_STATUS_RUNNING 3 +#define PROCESS_STATUS_MAYBE_HUNG 4 +#define PROCESS_STATUS_PROBABLY_HUNG 5 +#define PROCESS_STATUS_HUNG 6 + +// Process time thresholds +#define PROCESS_DEFAULT_HANG_WARNING_TIME 300 // 30 seconds +#define PROCESS_DEFAULT_HANG_ALERT_TIME 600 // 60 seconds +#define PROCESS_DEFAULT_HANG_RESTART_TIME 900 // 90 seconds +#define PROCESS_DEFAULT_SCHEDULE_INTERVAL 50 // 50 ticks +#define PROCESS_DEFAULT_SLEEP_INTERVAL 2 // 2 ticks +#define PROCESS_DEFAULT_CPU_THRESHOLD 90 // 90% + +//#define UPDATE_QUEUE_DEBUG \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/core/_stubs.dm b/code/controllers/ProcessScheduler/core/_stubs.dm new file mode 100644 index 00000000000..326fd29ac2a --- /dev/null +++ b/code/controllers/ProcessScheduler/core/_stubs.dm @@ -0,0 +1,38 @@ +/** + * _stubs.dm + * + * This file contains constructs that the process scheduler expects to exist + * in a standard ss13 fork. + */ +/* +/** + * message_admins + * + * sends a message to admins + */ +/proc/message_admins(msg) + world << msg +*/ +/** + * logTheThing + * + * In goonstation, this proc writes a message to either the world log or diary. + * + * Blame Keelin. + */ +/proc/logTheThing(type, source, target, text, diaryType) + if(diaryType) + world << "Diary: \[[diaryType]:[type]] [text]" + else + world << "Log: \[[type]] [text]" + +/** + * var/disposed + * + * In goonstation, disposed is set to 1 after an object enters the delete queue + * or the object is placed in an object pool (effectively out-of-play so to speak) + */ +/datum/var/disposed +// Garbage collection (controller). +/datum/var/gcDestroyed +/datum/var/timeDestroyed \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/core/process.dm b/code/controllers/ProcessScheduler/core/process.dm new file mode 100644 index 00000000000..89048113d30 --- /dev/null +++ b/code/controllers/ProcessScheduler/core/process.dm @@ -0,0 +1,317 @@ +// Process + +/datum/controller/process + /** + * State vars + */ + // Main controller ref + var/tmp/datum/controller/processScheduler/main + + // 1 if process is not running or queued + var/tmp/idle = 1 + + // 1 if process is queued + var/tmp/queued = 0 + + // 1 if process is running + var/tmp/running = 0 + + // 1 if process is blocked up + var/tmp/hung = 0 + + // 1 if process was killed + var/tmp/killed = 0 + + // Status text var + var/tmp/status + + // Previous status text var + var/tmp/previousStatus + + // 1 if process is disabled + var/tmp/disabled = 0 + + /** + * Config vars + */ + // Process name + var/name + + // Process schedule interval + // This controls how often the process would run under ideal conditions. + // If the process scheduler sees that the process has finished, it will wait until + // this amount of time has elapsed from the start of the previous run to start the + // process running again. + var/tmp/schedule_interval = PROCESS_DEFAULT_SCHEDULE_INTERVAL // run every 50 ticks + + // Process sleep interval + // This controls how often the process will yield (call sleep(0)) while it is running. + // Every concurrent process should sleep periodically while running in order to allow other + // processes to execute concurrently. + var/tmp/sleep_interval = PROCESS_DEFAULT_SLEEP_INTERVAL + + // hang_warning_time - this is the time (in 1/10 seconds) after which the server will begin to show "maybe hung" in the context window + var/tmp/hang_warning_time = PROCESS_DEFAULT_HANG_WARNING_TIME + + // hang_alert_time - After this much time(in 1/10 seconds), the server will send an admin debug message saying the process may be hung + var/tmp/hang_alert_time = PROCESS_DEFAULT_HANG_ALERT_TIME + + // hang_restart_time - After this much time(in 1/10 seconds), the server will automatically kill and restart the process. + var/tmp/hang_restart_time = PROCESS_DEFAULT_HANG_RESTART_TIME + + // cpu_threshold - if world.cpu >= cpu_threshold, scheck() will call sleep(1) to defer further work until the next tick. This keeps a process from driving a tick into overtime (causing perceptible lag) + var/tmp/cpu_threshold = PROCESS_DEFAULT_CPU_THRESHOLD + + // How many times in the current run has the process deferred work till the next tick? + var/tmp/cpu_defer_count = 0 + + /** + * recordkeeping vars + */ + + // Records the time (server ticks) at which the process last finished sleeping + var/tmp/last_slept = 0 + + // Records the time (s-ticks) at which the process last began running + var/tmp/run_start = 0 + + // Records the number of times this process has been killed and restarted + var/tmp/times_killed + + // Tick count + var/tmp/ticks = 0 + + var/tmp/last_task = "" + + var/tmp/last_object + +datum/controller/process/New(var/datum/controller/processScheduler/scheduler) + ..() + main = scheduler + previousStatus = "idle" + idle() + name = "process" + schedule_interval = 50 + sleep_interval = 2 + last_slept = 0 + run_start = 0 + ticks = 0 + last_task = 0 + last_object = null + +datum/controller/process/proc/started() + // Initialize last_slept so we can know when to sleep + last_slept = world.timeofday + + // Initialize run_start so we can detect hung processes. + run_start = world.timeofday + + // Initialize defer count + cpu_defer_count = 0 + + running() + main.processStarted(src) + + onStart() + +datum/controller/process/proc/finished() + ticks++ + idle() + main.processFinished(src) + + onFinish() + +datum/controller/process/proc/doWork() + +datum/controller/process/proc/setup() + +datum/controller/process/proc/process() + started() + doWork() + finished() + +datum/controller/process/proc/running() + idle = 0 + queued = 0 + running = 1 + hung = 0 + setStatus(PROCESS_STATUS_RUNNING) + +datum/controller/process/proc/idle() + queued = 0 + running = 0 + idle = 1 + hung = 0 + setStatus(PROCESS_STATUS_IDLE) + +datum/controller/process/proc/queued() + idle = 0 + running = 0 + queued = 1 + hung = 0 + setStatus(PROCESS_STATUS_QUEUED) + +datum/controller/process/proc/hung() + hung = 1 + setStatus(PROCESS_STATUS_HUNG) + +datum/controller/process/proc/handleHung() + var/datum/lastObj = last_object + var/lastObjType = "null" + if(istype(lastObj)) + lastObjType = lastObj.type + + // If world.timeofday has rolled over, then we need to adjust. + if (world.timeofday < run_start) + run_start -= 864000 + + var/msg = "[name] process hung at tick #[ticks]. Process was unresponsive for [(world.timeofday - run_start) / 10] seconds and was restarted. Last task: [last_task]. Last Object Type: [lastObjType]" + logTheThing("debug", null, null, msg) + logTheThing("diary", null, null, msg, "debug") + message_admins(msg) + + main.restartProcess(src.name) + +datum/controller/process/proc/kill() + if (!killed) + var/msg = "[name] process was killed at tick #[ticks]." + logTheThing("debug", null, null, msg) + logTheThing("diary", null, null, msg, "debug") + //finished() + + // Allow inheritors to clean up if needed + onKill() + + killed = TRUE + + // This should del + del(src) + +datum/controller/process/proc/scheck(var/tickId = 0) + if (killed) + // The kill proc is the only place where killed is set. + // The kill proc should have deleted this datum, and all sleeping procs that are + // owned by it. + CRASH("A killed process is still running somehow...") + + // For each tick the process defers, it increments the cpu_defer_count so we don't + // defer indefinitely + if (world.cpu >= cpu_threshold + cpu_defer_count * 10) + sleep(1) + cpu_defer_count++ + last_slept = world.timeofday + else + // If world.timeofday has rolled over, then we need to adjust. + if (world.timeofday < last_slept) + last_slept -= 864000 + + if (world.timeofday > last_slept + sleep_interval) + // If we haven't slept in sleep_interval ticks, sleep to allow other work to proceed. + sleep(0) + last_slept = world.timeofday + +datum/controller/process/proc/update() + // Clear delta + if(previousStatus != status) + setStatus(status) + + var/elapsedTime = getElapsedTime() + + if (elapsedTime > hang_restart_time) + hung() + else if (elapsedTime > hang_alert_time) + setStatus(PROCESS_STATUS_PROBABLY_HUNG) + else if (elapsedTime > hang_warning_time) + setStatus(PROCESS_STATUS_MAYBE_HUNG) + +datum/controller/process/proc/getElapsedTime() + if (world.timeofday < run_start) + return world.timeofday - (run_start - 864000) + return world.timeofday - run_start + +datum/controller/process/proc/tickDetail() + return + +datum/controller/process/proc/getContext() + return "[name][main.averageRunTime(src)][main.last_run_time[src]][main.highest_run_time[src]][ticks]\n" + +datum/controller/process/proc/getContextData() + return list( + "name" = name, + "averageRunTime" = main.averageRunTime(src), + "lastRunTime" = main.last_run_time[src], + "highestRunTime" = main.highest_run_time[src], + "ticks" = ticks, + "schedule" = schedule_interval, + "status" = getStatusText(), + "disabled" = disabled + ) + +datum/controller/process/proc/getStatus() + return status + +datum/controller/process/proc/getStatusText(var/s = 0) + if(!s) + s = status + switch(s) + if(PROCESS_STATUS_IDLE) + return "idle" + if(PROCESS_STATUS_QUEUED) + return "queued" + if(PROCESS_STATUS_RUNNING) + return "running" + if(PROCESS_STATUS_MAYBE_HUNG) + return "maybe hung" + if(PROCESS_STATUS_PROBABLY_HUNG) + return "probably hung" + if(PROCESS_STATUS_HUNG) + return "HUNG" + else + return "UNKNOWN" + +datum/controller/process/proc/getPreviousStatus() + return previousStatus + +datum/controller/process/proc/getPreviousStatusText() + return getStatusText(previousStatus) + +datum/controller/process/proc/setStatus(var/newStatus) + previousStatus = status + status = newStatus + +datum/controller/process/proc/setLastTask(var/task, var/object) + last_task = task + last_object = object + +datum/controller/process/proc/_copyStateFrom(var/datum/controller/process/target) + main = target.main + name = target.name + schedule_interval = target.schedule_interval + sleep_interval = target.sleep_interval + last_slept = 0 + run_start = 0 + times_killed = target.times_killed + ticks = target.ticks + last_task = target.last_task + last_object = target.last_object + copyStateFrom(target) + +datum/controller/process/proc/copyStateFrom(var/datum/controller/process/target) + +datum/controller/process/proc/onKill() + +datum/controller/process/proc/onStart() + +datum/controller/process/proc/onFinish() + +datum/controller/process/proc/disable() + disabled = 1 + +datum/controller/process/proc/enable() + disabled = 0 + +/datum/controller/process/proc/getLastRunTime() + return main.getProcessLastRunTime(src) + +/datum/controller/process/proc/getTicks() + return ticks diff --git a/code/controllers/ProcessScheduler/core/processScheduler.dm b/code/controllers/ProcessScheduler/core/processScheduler.dm new file mode 100644 index 00000000000..1be24045938 --- /dev/null +++ b/code/controllers/ProcessScheduler/core/processScheduler.dm @@ -0,0 +1,320 @@ +// Singleton instance of game_controller_new, setup in world.New() +var/global/datum/controller/processScheduler/processScheduler + +/datum/controller/processScheduler + // Processes known by the scheduler + var/tmp/datum/controller/process/list/processes = new + + // Processes that are currently running + var/tmp/datum/controller/process/list/running = new + + // Processes that are idle + var/tmp/datum/controller/process/list/idle = new + + // Processes that are queued to run + var/tmp/datum/controller/process/list/queued = new + + // Process name -> process object map + var/tmp/datum/controller/process/list/nameToProcessMap = new + + // Process last start times + var/tmp/datum/controller/process/list/last_start = new + + // Process last run durations + var/tmp/datum/controller/process/list/last_run_time = new + + // Per process list of the last 20 durations + var/tmp/datum/controller/process/list/last_twenty_run_times = new + + // Process highest run time + var/tmp/datum/controller/process/list/highest_run_time = new + + // Sleep 1 tick -- This may be too aggressive. + var/tmp/scheduler_sleep_interval = 1 + + // Controls whether the scheduler is running or not + var/tmp/isRunning = 0 + + // Setup for these processes will be deferred until all the other processes are set up. + var/tmp/list/deferredSetupList = new + +/** + * deferSetupFor + * @param path processPath + * If a process needs to be initialized after everything else, add it to + * the deferred setup list. On goonstation, only the ticker needs to have + * this treatment. + */ +/datum/controller/processScheduler/proc/deferSetupFor(var/processPath) + if (!(processPath in deferredSetupList)) + deferredSetupList += processPath + +/datum/controller/processScheduler/proc/setup() + // There can be only one + if(processScheduler && (processScheduler != src)) + del(src) + return 0 + + var/process + // Add all the processes we can find, except for the ticker + for (process in typesof(/datum/controller/process) - /datum/controller/process) + if (!(process in deferredSetupList)) + addProcess(new process(src)) + + for (process in deferredSetupList) + addProcess(new process(src)) + +/datum/controller/processScheduler/proc/start() + isRunning = 1 + spawn(0) + process() + +/datum/controller/processScheduler/proc/process() + while(isRunning) + checkRunningProcesses() + queueProcesses() + runQueuedProcesses() + sleep(scheduler_sleep_interval) + +/datum/controller/processScheduler/proc/stop() + isRunning = 0 + +/datum/controller/processScheduler/proc/checkRunningProcesses() + for(var/datum/controller/process/p in running) + p.update() + + if (isnull(p)) // Process was killed + continue + + var/status = p.getStatus() + var/previousStatus = p.getPreviousStatus() + + // Check status changes + if(status != previousStatus) + //Status changed. + + switch(status) + if(PROCESS_STATUS_MAYBE_HUNG) + message_admins("Process '[p.name]' is [p.getStatusText(status)].") + if(PROCESS_STATUS_PROBABLY_HUNG) + message_admins("Process '[p.name]' is [p.getStatusText(status)].") + if(PROCESS_STATUS_HUNG) + message_admins("Process '[p.name]' is [p.getStatusText(status)].") + p.handleHung() + +/datum/controller/processScheduler/proc/queueProcesses() + for(var/datum/controller/process/p in processes) + // Don't double-queue, don't queue running processes + if (p.disabled || p.running || p.queued || !p.idle) + continue + + // If world.timeofday has rolled over, then we need to adjust. + if (world.timeofday < last_start[p]) + last_start[p] -= 864000 + + // If the process should be running by now, go ahead and queue it + if (world.timeofday > last_start[p] + p.schedule_interval) + setQueuedProcessState(p) + +/datum/controller/processScheduler/proc/runQueuedProcesses() + for(var/datum/controller/process/p in queued) + runProcess(p) + +/datum/controller/processScheduler/proc/addProcess(var/datum/controller/process/process) + processes.Add(process) + process.idle() + idle.Add(process) + + // init recordkeeping vars + last_start.Add(process) + last_start[process] = 0 + last_run_time.Add(process) + last_run_time[process] = 0 + last_twenty_run_times.Add(process) + last_twenty_run_times[process] = list() + highest_run_time.Add(process) + highest_run_time[process] = 0 + + // init starts and stops record starts + recordStart(process, 0) + recordEnd(process, 0) + + // Set up process + process.setup() + + // Save process in the name -> process map + nameToProcessMap[process.name] = process + +/datum/controller/processScheduler/proc/replaceProcess(var/datum/controller/process/oldProcess, var/datum/controller/process/newProcess) + processes.Remove(oldProcess) + processes.Add(newProcess) + + newProcess.idle() + idle.Remove(oldProcess) + running.Remove(oldProcess) + queued.Remove(oldProcess) + idle.Add(newProcess) + + last_start.Remove(oldProcess) + last_start.Add(newProcess) + last_start[newProcess] = 0 + + last_run_time.Add(newProcess) + last_run_time[newProcess] = last_run_time[oldProcess] + last_run_time.Remove(oldProcess) + + last_twenty_run_times.Add(newProcess) + last_twenty_run_times[newProcess] = last_twenty_run_times[oldProcess] + last_twenty_run_times.Remove(oldProcess) + + highest_run_time.Add(newProcess) + highest_run_time[newProcess] = highest_run_time[oldProcess] + highest_run_time.Remove(oldProcess) + + recordStart(newProcess, 0) + recordEnd(newProcess, 0) + + nameToProcessMap[newProcess.name] = newProcess + + +/datum/controller/processScheduler/proc/runProcess(var/datum/controller/process/process) + spawn(0) + process.process() + +/datum/controller/processScheduler/proc/processStarted(var/datum/controller/process/process) + setRunningProcessState(process) + recordStart(process) + +/datum/controller/processScheduler/proc/processFinished(var/datum/controller/process/process) + setIdleProcessState(process) + recordEnd(process) + +/datum/controller/processScheduler/proc/setIdleProcessState(var/datum/controller/process/process) + if (process in running) + running -= process + if (process in queued) + queued -= process + if (!(process in idle)) + idle += process + + process.idle() + +/datum/controller/processScheduler/proc/setQueuedProcessState(var/datum/controller/process/process) + if (process in running) + running -= process + if (process in idle) + idle -= process + if (!(process in queued)) + queued += process + + // The other state transitions are handled internally by the process. + process.queued() + +/datum/controller/processScheduler/proc/setRunningProcessState(var/datum/controller/process/process) + if (process in queued) + queued -= process + if (process in idle) + idle -= process + if (!(process in running)) + running += process + + process.running() + +/datum/controller/processScheduler/proc/recordStart(var/datum/controller/process/process, var/time = null) + if (isnull(time)) + time = world.timeofday + + last_start[process] = time + +/datum/controller/processScheduler/proc/recordEnd(var/datum/controller/process/process, var/time = null) + if (isnull(time)) + time = world.timeofday + + // If world.timeofday has rolled over, then we need to adjust. + if (time < last_start[process]) + last_start[process] -= 864000 + + var/lastRunTime = time - last_start[process] + + if(lastRunTime < 0) + lastRunTime = 0 + + recordRunTime(process, lastRunTime) + +/** + * recordRunTime + * Records a run time for a process + */ +/datum/controller/processScheduler/proc/recordRunTime(var/datum/controller/process/process, time) + last_run_time[process] = time + if(time > highest_run_time[process]) + highest_run_time[process] = time + + var/list/lastTwenty = last_twenty_run_times[process] + if (lastTwenty.len == 20) + lastTwenty.Cut(1, 2) + lastTwenty.len++ + lastTwenty[lastTwenty.len] = time + +/** + * averageRunTime + * returns the average run time (over the last 20) of the process + */ +/datum/controller/processScheduler/proc/averageRunTime(var/datum/controller/process/process) + var/lastTwenty = last_twenty_run_times[process] + + var/t = 0 + var/c = 0 + for(var/time in lastTwenty) + t += time + c++ + + if(c > 0) + return t / c + return c + +/datum/controller/processScheduler/proc/getStatusData() + var/list/data = new + + for (var/datum/controller/process/p in processes) + data.len++ + data[data.len] = p.getContextData() + + return data + +/datum/controller/processScheduler/proc/getProcessCount() + return processes.len + +/datum/controller/processScheduler/proc/hasProcess(var/processName as text) + if (nameToProcessMap[processName]) + return 1 + +/datum/controller/processScheduler/proc/killProcess(var/processName as text) + restartProcess(processName) + +/datum/controller/processScheduler/proc/restartProcess(var/processName as text) + if (hasProcess(processName)) + var/datum/controller/process/oldInstance = nameToProcessMap[processName] + var/datum/controller/process/newInstance = new oldInstance.type(src) + newInstance._copyStateFrom(oldInstance) + replaceProcess(oldInstance, newInstance) + oldInstance.kill() + +/datum/controller/processScheduler/proc/enableProcess(var/processName as text) + if (hasProcess(processName)) + var/datum/controller/process/process = nameToProcessMap[processName] + process.enable() + +/datum/controller/processScheduler/proc/disableProcess(var/processName as text) + if (hasProcess(processName)) + var/datum/controller/process/process = nameToProcessMap[processName] + process.disable() + +/datum/controller/processScheduler/proc/getProcess(var/name) + return nameToProcessMap[name] + +/datum/controller/processScheduler/proc/getProcessLastRunTime(var/datum/controller/process/process) + return last_run_time[process] + +/datum/controller/processScheduler/proc/getIsRunning() + return isRunning diff --git a/code/controllers/ProcessScheduler/core/updateQueue.dm b/code/controllers/ProcessScheduler/core/updateQueue.dm new file mode 100644 index 00000000000..118b6692b5a --- /dev/null +++ b/code/controllers/ProcessScheduler/core/updateQueue.dm @@ -0,0 +1,127 @@ +/** + * updateQueue.dm + */ + +#ifdef UPDATE_QUEUE_DEBUG +#define uq_dbg(text) world << text +#else +#define uq_dbg(text) +#endif +/datum/updateQueue + var/tmp/list/objects + var/tmp/previousStart + var/tmp/procName + var/tmp/list/arguments + var/tmp/datum/updateQueueWorker/currentWorker + var/tmp/workerTimeout + var/tmp/adjustedWorkerTimeout + var/tmp/currentKillCount + var/tmp/totalKillCount + +/datum/updateQueue/New(list/objects = list(), procName = "update", list/arguments = list(), workerTimeout = 2, inplace = 0) + ..() + + uq_dbg("Update queue created.") + + // Init proc allows for recycling the worker. + init(objects = objects, procName = procName, arguments = arguments, workerTimeout = workerTimeout, inplace = inplace) + +/** + * init + * @param list objects objects to update + * @param text procName the proc to call on each item in the object list + * @param list arguments optional arguments to pass to the update proc + * @param number workerTimeout number of ticks to wait for an update to + finish before forking a new update worker + * @param bool inplace whether the updateQueue should make a copy of objects. + the internal list will be modified, so it is usually + a good idea to leave this alone. Default behavior is to + copy. + */ +/datum/updateQueue/proc/init(list/objects = list(), procName = "update", list/arguments = list(), workerTimeout = 2, inplace = 0) + uq_dbg("Update queue initialization started.") + + if (!inplace) + // Make an internal copy of the list so we're not modifying the original. + initList(objects) + else + src.objects = objects + + // Init vars + src.procName = procName + src.arguments = arguments + src.workerTimeout = workerTimeout + + adjustedWorkerTimeout = workerTimeout + currentKillCount = 0 + totalKillCount = 0 + + uq_dbg("Update queue initialization finished. procName = '[procName]'") + +/datum/updateQueue/proc/initList(list/toCopy) + /** + * We will copy the list in reverse order, as our doWork proc + * will access them by popping an element off the end of the list. + * This ends up being quite a lot faster than taking elements off + * the head of the list. + */ + objects = new + + uq_dbg("Copying [toCopy.len] items for processing.") + + for(var/i=toCopy.len,i>0,) + objects.len++ + objects[objects.len] = toCopy[i--] + +/datum/updateQueue/proc/Run() + uq_dbg("Starting run...") + + startWorker() + while (istype(currentWorker) && !currentWorker.finished) + sleep(2) + checkWorker() + + uq_dbg("UpdateQueue completed run.") + +/datum/updateQueue/proc/checkWorker() + if(istype(currentWorker)) + // If world.timeofday has rolled over, then we need to adjust. + if(world.timeofday < currentWorker.lastStart) + currentWorker.lastStart -= 864000 + + if(world.timeofday - currentWorker.lastStart > adjustedWorkerTimeout) + // This worker is a bit slow, let's spawn a new one and kill the old one. + uq_dbg("Current worker is lagging... starting a new one.") + killWorker() + startWorker() + else // No worker! + uq_dbg("update queue ended up without a worker... starting a new one...") + startWorker() + +/datum/updateQueue/proc/startWorker() + // only run the worker if we have objects to work on + if(objects.len) + uq_dbg("Starting worker process.") + + // No need to create a fresh worker if we already have one... + if (istype(currentWorker)) + currentWorker.init(objects, procName, arguments) + else + currentWorker = new(objects, procName, arguments) + currentWorker.start() + else + uq_dbg("Queue is empty. No worker was started.") + currentWorker = null + +/datum/updateQueue/proc/killWorker() + // Kill the worker + currentWorker.kill() + currentWorker = null + // After we kill a worker, yield so that if the worker's been tying up the cpu, other stuff can immediately resume + sleep(-1) + currentKillCount++ + totalKillCount++ + if (currentKillCount >= 3) + uq_dbg("[currentKillCount] workers have been killed with a timeout of [adjustedWorkerTimeout]. Increasing worker timeout to compensate.") + adjustedWorkerTimeout++ + currentKillCount = 0 \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/core/updateQueueWorker.dm b/code/controllers/ProcessScheduler/core/updateQueueWorker.dm new file mode 100644 index 00000000000..66f66bbcc01 --- /dev/null +++ b/code/controllers/ProcessScheduler/core/updateQueueWorker.dm @@ -0,0 +1,83 @@ +datum/updateQueueWorker + var/tmp/list/objects + var/tmp/killed + var/tmp/finished + var/tmp/procName + var/tmp/list/arguments + var/tmp/lastStart + var/tmp/cpuThreshold + +datum/updateQueueWorker/New(var/list/objects, var/procName, var/list/arguments, var/cpuThreshold = 90) + ..() + uq_dbg("updateQueueWorker created.") + + init(objects, procName, arguments, cpuThreshold) + +datum/updateQueueWorker/proc/init(var/list/objects, var/procName, var/list/arguments, var/cpuThreshold = 90) + src.objects = objects + src.procName = procName + src.arguments = arguments + src.cpuThreshold = cpuThreshold + + killed = 0 + finished = 0 + +datum/updateQueueWorker/proc/doWork() + // If there's nothing left to execute or we were killed, mark finished and return. + if (!objects || !objects.len) return finished() + + lastStart = world.timeofday // Absolute number of ticks since the world started up + + var/datum/object = objects[objects.len] // Pull out the object + objects.len-- // Remove the object from the list + + if (istype(object) && !isturf(object) && !object.disposed && isnull(object.gcDestroyed)) // We only work with real objects + call(object, procName)(arglist(arguments)) + + // If there's nothing left to execute + // or we were killed while running the above code, mark finished and return. + if (!objects || !objects.len) return finished() + + if (world.cpu > cpuThreshold) + // We don't want to force a tick into overtime! + // If the tick is about to go overtime, spawn the next update to go + // in the next tick. + uq_dbg("tick went into overtime with world.cpu = [world.cpu], deferred next update to next tick [1+(world.time / world.tick_lag)]") + + spawn(1) + doWork() + else + spawn(0) // Execute anonymous function immediately as if we were in a while loop... + doWork() + +datum/updateQueueWorker/proc/finished() + uq_dbg("updateQueueWorker finished.") + /** + * If the worker was killed while it was working on something, it + * should delete itself when it finally finishes working on it. + * Meanwhile, the updateQueue will have proceeded on with the rest of + * the queue. This will also terminate the spawned function that was + * created in the kill() proc. + */ + if(killed) + del(src) + + finished = 1 + +datum/updateQueueWorker/proc/kill() + uq_dbg("updateQueueWorker killed.") + killed = 1 + objects = null + + /** + * If the worker is not done in 30 seconds after it's killed, + * we'll forcibly delete it, causing the anonymous function it was + * running to be terminated. Hasta la vista, baby. + */ + spawn(300) + del(src) + +datum/updateQueueWorker/proc/start() + uq_dbg("updateQueueWorker started.") + spawn(0) + doWork() \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/package.json b/code/controllers/ProcessScheduler/package.json new file mode 100644 index 00000000000..f699553fc61 --- /dev/null +++ b/code/controllers/ProcessScheduler/package.json @@ -0,0 +1,28 @@ +{ + "name": "ProcessScheduler", + "version": "1.0.0", + "description": "BYOND SS13 Process Scheduler", + "main": "processScheduler.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://github.com/goonstation/ProcessScheduler.git" + }, + "keywords": [ + "byond", + "ss13", + "process", + "scheduler" + ], + "author": "Volundr", + "license": "CC-BY-NC", + "bugs": { + "url": "https://github.com/goonstation/ProcessScheduler/issues" + }, + "homepage": "https://github.com/goonstation/ProcessScheduler", + "dependencies": { + "bower": "*" + } +} diff --git a/code/controllers/ProcessScheduler/test/processScheduler.js b/code/controllers/ProcessScheduler/test/processScheduler.js new file mode 100644 index 00000000000..0a4f111355d --- /dev/null +++ b/code/controllers/ProcessScheduler/test/processScheduler.js @@ -0,0 +1,56 @@ +(function ($) { + function setRef(theRef) { + ref = theRef; + } + + function jax(action, data) { + if (typeof data === 'undefined') + data = {}; + var params = []; + for (var k in data) { + if (data.hasOwnProperty(k)) { + params.push(encodeURIComponent(k) + '=' + encodeURIComponent(data[k])); + } + } + var newLoc = '?src=' + ref + ';action=' + action + ';' + params.join(';'); + window.location = newLoc; + } + + function requestRefresh(e) { + jax("refresh", null); + } + + function handleRefresh(processTable) { + $('#processTable').html(processTable); + initProcessTableButtons(); + } + + function requestKill(e) { + var button = $(e.currentTarget); + jax("kill", {name: button.data("process-name")}); + } + + function requestEnable(e) { + var button = $(e.currentTarget); + jax("enable", {name: button.data("process-name")}); + } + + function requestDisable(e) { + var button = $(e.currentTarget); + jax("disable", {name: button.data("process-name")}); + } + + function initProcessTableButtons() { + $(".kill-btn").on("click", requestKill); + $(".enable-btn").on("click", requestEnable); + $(".disable-btn").on("click", requestDisable); + } + + window.setRef = setRef; + window.handleRefresh = handleRefresh; + + $(function() { + initProcessTableButtons(); + $('#btn-refresh').on("click", requestRefresh); + }); +}(jQuery)); \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/test/processSchedulerView.dm b/code/controllers/ProcessScheduler/test/processSchedulerView.dm new file mode 100644 index 00000000000..ae78b3f0154 --- /dev/null +++ b/code/controllers/ProcessScheduler/test/processSchedulerView.dm @@ -0,0 +1,94 @@ +/datum/processSchedulerView + +/datum/processSchedulerView/Topic(href, href_list) + if (!href_list["action"]) + return + + switch (href_list["action"]) + if ("kill") + var/toKill = href_list["name"] + processScheduler.killProcess(toKill) + refreshProcessTable() + if ("enable") + var/toEnable = href_list["name"] + processScheduler.enableProcess(toEnable) + refreshProcessTable() + if ("disable") + var/toDisable = href_list["name"] + processScheduler.disableProcess(toDisable) + refreshProcessTable() + if ("refresh") + refreshProcessTable() + +/datum/processSchedulerView/proc/refreshProcessTable() + windowCall("handleRefresh", getProcessTable()) + +/datum/processSchedulerView/proc/windowCall(var/function, var/data = null) + usr << output(data, "processSchedulerContext.browser:[function]") + +/datum/processSchedulerView/proc/getProcessTable() + var/text = "" + // and the context of each + for (var/list/data in processScheduler.getStatusData()) + text += "" + text += "" + text += "" + text += "" + text += "" + text += "" + text += "" + text += "" + text += "" + text += "" + + text += "
NameAvg(s)Last(s)Highest(s)TickcountTickrateStateAction
[data["name"]][num2text(data["averageRunTime"]/10,3)][num2text(data["lastRunTime"]/10,3)][num2text(data["highestRunTime"]/10,3)][num2text(data["ticks"],4)][data["schedule"]][data["status"]]" + if (data["disabled"]) + text += "" + else + text += "" + text += "
" + return text + +/** + * getContext + * Outputs an interface showing stats for all processes. + */ +/datum/processSchedulerView/proc/getContext() + bootstrap_browse() + usr << browse('processScheduler.js', "file=processScheduler.js;display=0") + + var/text = {" + Process Scheduler Detail + + [bootstrap_includes()] + + + +

Process Scheduler

+
+ +
+ +

The process scheduler controls [processScheduler.getProcessCount()] loops.

"} + + text += "
" + text += getProcessTable() + text += "
" + + usr << browse(text, "window=processSchedulerContext;size=800x600") + +/datum/processSchedulerView/proc/bootstrap_browse() + usr << browse('bower_components/jquery/dist/jquery.min.js', "file=jquery.min.js;display=0") + usr << browse('bower_components/bootstrap2.3.2/bootstrap/js/bootstrap.min.js', "file=bootstrap.min.js;display=0") + usr << browse('bower_components/bootstrap2.3.2/bootstrap/css/bootstrap.min.css', "file=bootstrap.min.css;display=0") + usr << browse('bower_components/bootstrap2.3.2/bootstrap/img/glyphicons-halflings-white.png', "file=glyphicons-halflings-white.png;display=0") + usr << browse('bower_components/bootstrap2.3.2/bootstrap/img/glyphicons-halflings.png', "file=glyphicons-halflings.png;display=0") + usr << browse('bower_components/json2/json2.js', "file=json2.js;display=0") + +/datum/processSchedulerView/proc/bootstrap_includes() + return {" + + + + + "} diff --git a/code/controllers/ProcessScheduler/test/testDyingUpdateQueueProcess.dm b/code/controllers/ProcessScheduler/test/testDyingUpdateQueueProcess.dm new file mode 100644 index 00000000000..d08ec46c7da --- /dev/null +++ b/code/controllers/ProcessScheduler/test/testDyingUpdateQueueProcess.dm @@ -0,0 +1,27 @@ +/** + * testDyingUpdateQueueProcess + * This process is an example of a process using an updateQueue. + * The datums updated by this process behave badly and block the update loop + * by sleeping. If you #define UPDATE_QUEUE_DEBUG, you will see the updateQueue + * killing off its worker processes and spawning new ones to work around slow + * updates. This means that if you have a code path that sleeps for a long time + * in mob.Life once in a blue moon, the mob update loop will not hang. + */ +/datum/slowTestDatum/proc/wackyUpdateProcessName() + sleep(rand(0,20)) // Randomly REALLY slow :| + +/datum/controller/process/testDyingUpdateQueueProcess + var/tmp/datum/updateQueue/updateQueueInstance + var/tmp/list/testDatums = list() + +/datum/controller/process/testDyingUpdateQueueProcess/setup() + name = "Dying UpdateQueue Process" + schedule_interval = 30 // every 3 seconds + updateQueueInstance = new + for(var/i = 1, i < 30, i++) + testDatums.Add(new /datum/slowTestDatum) + +/datum/controller/process/testDyingUpdateQueueProcess/doWork() + updateQueueInstance.init(testDatums, "wackyUpdateProcessName") + updateQueueInstance.Run() + \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/test/testHarness.dm b/code/controllers/ProcessScheduler/test/testHarness.dm new file mode 100644 index 00000000000..2b5f1dff813 --- /dev/null +++ b/code/controllers/ProcessScheduler/test/testHarness.dm @@ -0,0 +1,35 @@ +/* + These are simple defaults for your project. + */ +#define DEBUG + +var/global/datum/processSchedulerView/processSchedulerView + +world + loop_checks = 0 + New() + ..() + processScheduler = new + processSchedulerView = new + +mob + step_size = 8 + + New() + ..() + + + verb + startProcessScheduler() + set name = "Start Process Scheduler" + processScheduler.setup() + processScheduler.start() + + getProcessSchedulerContext() + set name = "Get Process Scheduler Status Panel" + processSchedulerView.getContext() + + runUpdateQueueTests() + set name = "Run Update Queue Testsuite" + var/datum/updateQueueTests/t = new + t.runTests() \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/test/testHungProcess.dm b/code/controllers/ProcessScheduler/test/testHungProcess.dm new file mode 100644 index 00000000000..ced05dd4d70 --- /dev/null +++ b/code/controllers/ProcessScheduler/test/testHungProcess.dm @@ -0,0 +1,15 @@ +/** + * testHungProcess + * This process is an example of a simple update loop process that hangs. + */ + +/datum/controller/process/testHungProcess/setup() + name = "Hung Process" + schedule_interval = 30 // every 3 seconds + +/datum/controller/process/testHungProcess/doWork() + sleep(1000) // FUCK + // scheck is also responsible for handling hung processes. If a process + // hangs, and later resumes, but has already been killed by the scheduler, + // scheck will force the process to bail out. + scheck() \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/test/testNiceProcess.dm b/code/controllers/ProcessScheduler/test/testNiceProcess.dm new file mode 100644 index 00000000000..aa921bc62fa --- /dev/null +++ b/code/controllers/ProcessScheduler/test/testNiceProcess.dm @@ -0,0 +1,13 @@ +/** + * testNiceProcess + * This process is an example of a simple update loop process that is + * relatively fast. + */ + +/datum/controller/process/testNiceProcess/setup() + name = "Nice Process" + schedule_interval = 10 // every second + +/datum/controller/process/testNiceProcess/doWork() + sleep(rand(1,5)) // Just to pretend we're doing something + \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/test/testSlowProcess.dm b/code/controllers/ProcessScheduler/test/testSlowProcess.dm new file mode 100644 index 00000000000..b7c9e6e21e8 --- /dev/null +++ b/code/controllers/ProcessScheduler/test/testSlowProcess.dm @@ -0,0 +1,28 @@ +/** + * testSlowProcess + * This process is an example of a simple update loop process that is slow. + * The update loop here sleeps inside to provide an example, but if you had + * a computationally intensive loop process that is simply slow, you can use + * scheck() inside the loop to force it to yield periodically according to + * the sleep_interval var. By default, scheck will cause a loop to sleep every + * 2 ticks. + */ + +/datum/controller/process/testSlowProcess/setup() + name = "Slow Process" + schedule_interval = 30 // every 3 seconds + +/datum/controller/process/testSlowProcess/doWork() + // set background = 1 will cause loop constructs to sleep periodically, + // whenever the BYOND scheduler deems it productive to do so. + // This behavior is not always sufficient, nor is it always consistent. + // Rather than leaving it up to the BYOND scheduler, we can control it + // ourselves and leave nothing to the black box. + set background = 1 + + for(var/i=1,i<30,i++) + // Just to pretend we're doing something here + sleep(rand(3, 5)) + + // Forces this loop to yield(sleep) periodically. + scheck() \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/test/testUpdateQueue.dm b/code/controllers/ProcessScheduler/test/testUpdateQueue.dm new file mode 100644 index 00000000000..07b64e927f3 --- /dev/null +++ b/code/controllers/ProcessScheduler/test/testUpdateQueue.dm @@ -0,0 +1,209 @@ +var/global/list/updateQueueTestCount = list() + +/datum/updateQueueTests + var/start + proc + runTests() + world << "Running 9 tests..." + testUpdateQueuePerformance() + sleep(1) + testInplace() + sleep(1) + testInplaceUpdateQueuePerformance() + sleep(1) + testUpdateQueueReinit() + sleep(1) + testCrashingQueue() + sleep(1) + testEmptyQueue() + sleep(1) + testManySlowItemsInQueue() + sleep(1) + testVariableWorkerTimeout() + sleep(1) + testReallySlowItemInQueue() + sleep(1) + world << "Finished!" + + beginTiming() + start = world.time + + endTiming(text) + var/time = (world.time - start) / world.tick_lag + world << {"Performance - [text] - [time] ticks"} + + getCount() + return updateQueueTestCount[updateQueueTestCount.len] + + incrementTestCount() + updateQueueTestCount.len++ + updateQueueTestCount[updateQueueTestCount.len] = 0 + + assertCountEquals(count, text) + assertThat(getCount() == count, text) + + assertCountLessThan(count, text) + assertThat(getCount() < count, text) + + assertCountGreaterThan(count, text) + assertThat(getCount() > count, text) + + assertThat(condition, text) + if (condition) + world << {"PASS: [text]"} + else + world << {"FAIL: [text]"} + + testUpdateQueuePerformance() + incrementTestCount() + var/list/objs = new + for(var/i=1,i<=100000,i++) + objs.Add(new /datum/uqTestDatum/fast(updateQueueTestCount.len)) + + var/datum/updateQueue/uq = new(objs) + + beginTiming() + uq.Run() + endTiming("updating 100000 simple objects") + + assertCountEquals(100000, "test that update queue updates all objects expected") + del(objs) + del(uq) + + testUpdateQueueReinit() + incrementTestCount() + var/list/objs = new + for(var/i=1,i<=100,i++) + objs.Add(new /datum/uqTestDatum/fast(updateQueueTestCount.len)) + + var/datum/updateQueue/uq = new(objs) + uq.Run() + objs = new + + for(var/i=1,i<=100,i++) + objs.Add(new /datum/uqTestDatum/fast(updateQueueTestCount.len)) + uq.init(objs) + uq.Run() + assertCountEquals(200, "test that update queue reinitializes properly and updates all objects as expected.") + del(objs) + del(uq) + + testInplace() + incrementTestCount() + var/list/objs = new + for(var/i=1,i<=100,i++) + objs.Add(new /datum/uqTestDatum/fast(updateQueueTestCount.len)) + var/datum/updateQueue/uq = new(objects = objs, inplace = 1) + uq.Run() + assertThat(objs.len == 0, "test that update queue inplace option really works inplace") + assertCountEquals(100, "test that inplace update queue updates the right number of objects") + del(objs) + del(uq) + + testInplaceUpdateQueuePerformance() + incrementTestCount() + var/list/objs = new + for(var/i=1,i<=100000,i++) + objs.Add(new /datum/uqTestDatum/fast(updateQueueTestCount.len)) + + var/datum/updateQueue/uq = new(objs) + + beginTiming() + uq.Run() + endTiming("updating 100000 simple objects in place") + del(objs) + del(uq) + + testCrashingQueue() + incrementTestCount() + var/list/objs = new + for(var/i=1,i<=10,i++) + objs.Add(new /datum/uqTestDatum/fast(updateQueueTestCount.len)) + objs.Add(new /datum/uqTestDatum/crasher(updateQueueTestCount.len)) + for(var/i=1,i<=10,i++) + objs.Add(new /datum/uqTestDatum/fast(updateQueueTestCount.len)) + + var/datum/updateQueue/uq = new(objs) + uq.Run() + assertCountEquals(20, "test that update queue handles crashed update procs OK") + del(objs) + del(uq) + + testEmptyQueue() + incrementTestCount() + var/list/objs = new + var/datum/updateQueue/uq = new(objs) + uq.Run() + assertCountEquals(0, "test that update queue doesn't barf on empty lists") + del(objs) + del(uq) + + testManySlowItemsInQueue() + incrementTestCount() + var/list/objs = new + for(var/i=1,i<=30,i++) + objs.Add(new /datum/uqTestDatum/slow(updateQueueTestCount.len)) + var/datum/updateQueue/uq = new(objs) + uq.Run() + assertCountEquals(30, "test that update queue slows down execution if too many objects are slow to update") + del(objs) + del(uq) + + testVariableWorkerTimeout() + incrementTestCount() + var/list/objs = new + for(var/i=1,i<=20,i++) + objs.Add(new /datum/uqTestDatum/slow(updateQueueTestCount.len)) + var/datum/updateQueue/uq = new(objs, workerTimeout=6) + uq.Run() + assertCountEquals(20, "test that variable worker timeout works properly") + del(objs) + del(uq) + + testReallySlowItemInQueue() + incrementTestCount() + var/list/objs = new + for(var/i=1,i<=10,i++) + objs.Add(new /datum/uqTestDatum/fast(updateQueueTestCount.len)) + objs.Add(new /datum/uqTestDatum/reallySlow(updateQueueTestCount.len)) + for(var/i=1,i<=10,i++) + objs.Add(new /datum/uqTestDatum/fast(updateQueueTestCount.len)) + var/datum/updateQueue/uq = new(objs) + uq.Run() + assertCountEquals(20, "test that update queue skips objects that are too slow to update") + del(objs) + del(uq) + + + +datum/uqTestDatum + var/testNum + New(testNum) + ..() + src.testNum = testNum + proc/update() + updateQueueTestCount[testNum]++ + proc/lag(cycles) + set background = 1 + for(var/i=0,i 5) + world << "RUNTIMES IN ATMOS TICKER. Killing air simulation!" + world.log << "### ZAS SHUTDOWN" + + message_admins("ZASALERT: Shutting down! status: [air_master.tick_progress]") + log_admin("ZASALERT: Shutting down! status: [air_master.tick_progress]") + + air_processing_killed = TRUE + air_master.failed_ticks = 0 diff --git a/code/controllers/Processes/bot.dm b/code/controllers/Processes/bot.dm new file mode 100644 index 00000000000..b93324d0901 --- /dev/null +++ b/code/controllers/Processes/bot.dm @@ -0,0 +1,20 @@ +/datum/controller/process/bot + var/tmp/datum/updateQueue/updateQueueInstance + +/datum/controller/process/bot/setup() + name = "bot" + schedule_interval = 20 // every 2 seconds + updateQueueInstance = new + +/datum/controller/process/bot/started() + ..() + if(!updateQueueInstance) + if(!aibots) + aibots = list() + else if(aibots.len) + updateQueueInstance = new + +/datum/controller/process/bot/doWork() + if(updateQueueInstance) + updateQueueInstance.init(aibots, "bot_process") + updateQueueInstance.Run() diff --git a/code/controllers/Processes/disease.dm b/code/controllers/Processes/disease.dm new file mode 100644 index 00000000000..a8d840097ec --- /dev/null +++ b/code/controllers/Processes/disease.dm @@ -0,0 +1,11 @@ +/datum/controller/process/disease + var/tmp/datum/updateQueue/updateQueueInstance + +/datum/controller/process/disease/setup() + name = "disease" + schedule_interval = 20 // every 2 seconds + updateQueueInstance = new + +/datum/controller/process/disease/doWork() + updateQueueInstance.init(active_diseases, "process") + updateQueueInstance.Run() diff --git a/code/controllers/Processes/emergencyShuttle.dm b/code/controllers/Processes/emergencyShuttle.dm new file mode 100644 index 00000000000..e7289311b95 --- /dev/null +++ b/code/controllers/Processes/emergencyShuttle.dm @@ -0,0 +1,9 @@ +/datum/controller/process/emergencyShuttle/setup() + name = "emergency shuttle" + schedule_interval = 20 // every 2 seconds + + if(!emergency_shuttle) + emergency_shuttle = new + +/datum/controller/process/emergencyShuttle/doWork() + emergency_shuttle.process() diff --git a/code/controllers/Processes/event.dm b/code/controllers/Processes/event.dm new file mode 100644 index 00000000000..9948ef18ea6 --- /dev/null +++ b/code/controllers/Processes/event.dm @@ -0,0 +1,6 @@ +/datum/controller/process/event/setup() + name = "event" + schedule_interval = 20 // every 2 seconds + +/datum/controller/process/event/doWork() + event_manager.process() \ No newline at end of file diff --git a/code/controllers/Processes/garbage.dm b/code/controllers/Processes/garbage.dm new file mode 100644 index 00000000000..f589c641f5b --- /dev/null +++ b/code/controllers/Processes/garbage.dm @@ -0,0 +1,10 @@ +/datum/controller/process/garbage/setup() + name = "garbage" + schedule_interval = 20 // every 2 seconds + + if(!garbageCollector) + garbageCollector = new + +/datum/controller/process/garbage/doWork() + garbageCollector.process() + scheck() \ No newline at end of file diff --git a/code/controllers/Processes/inactivity.dm b/code/controllers/Processes/inactivity.dm new file mode 100644 index 00000000000..e4cc04e4871 --- /dev/null +++ b/code/controllers/Processes/inactivity.dm @@ -0,0 +1,16 @@ +/*/datum/controller/process/inactivity/setup() + name = "inactivity" + schedule_interval = INACTIVITY_KICK + +/datum/controller/process/inactivity/doWork() + if(config.kick_inactive) + for(var/client/C in clients) + if(C.is_afk(INACTIVITY_KICK)) + if(!istype(C.mob, /mob/dead)) + log_access("AFK: [key_name(C)]") + C << "You have been inactive for more than 10 minutes and have been disconnected." + del(C) + + scheck() + +#undef INACTIVITY_KICK*/ diff --git a/code/controllers/Processes/lighting.dm b/code/controllers/Processes/lighting.dm new file mode 100644 index 00000000000..bbf9ecd2f99 --- /dev/null +++ b/code/controllers/Processes/lighting.dm @@ -0,0 +1,26 @@ +/datum/controller/process/lighting/setup() + name = "lighting" + schedule_interval = 5 // every .5 second + lighting_controller.Initialize() + +/datum/controller/process/lighting/doWork() + lighting_controller.lights_workload_max = \ + max(lighting_controller.lights_workload_max, lighting_controller.lights.len) + + for(var/datum/light_source/L in lighting_controller.lights) + if(L && L.check()) + lighting_controller.lights.Remove(L) + + scheck() + + lighting_controller.changed_turfs_workload_max = \ + max(lighting_controller.changed_turfs_workload_max, lighting_controller.changed_turfs.len) + + for(var/turf/T in lighting_controller.changed_turfs) + if(T && T.lighting_changed) + T.shift_to_subarea() + + scheck() + + if(lighting_controller.changed_turfs && lighting_controller.changed_turfs.len) + lighting_controller.changed_turfs.len = 0 // reset the changed list diff --git a/code/controllers/Processes/machinery.dm b/code/controllers/Processes/machinery.dm new file mode 100644 index 00000000000..52274a519af --- /dev/null +++ b/code/controllers/Processes/machinery.dm @@ -0,0 +1,34 @@ +/datum/controller/process/machinery/setup() + name = "machinery" + schedule_interval = 20 // every 2 seconds + +/datum/controller/process/machinery/doWork() + //#ifdef PROFILE_MACHINES + //machine_profiling.len = 0 + //#endif + + for(var/obj/machinery/M in machines) + if(M && !M.gcDestroyed) + #ifdef PROFILE_MACHINES + var/time_start = world.timeofday + #endif + + if(M.process() == PROCESS_KILL) + //M.inMachineList = 0 We don't use this debugging function + machines.Remove(M) + continue + + if(M && M.use_power) + M.auto_use_power() + + #ifdef PROFILE_MACHINES + var/time_end = world.timeofday + + if(!(M.type in machine_profiling)) + machine_profiling[M.type] = 0 + + machine_profiling[M.type] += (time_end - time_start) + #endif + + scheck() + diff --git a/code/controllers/Processes/mob.dm b/code/controllers/Processes/mob.dm new file mode 100644 index 00000000000..b3765b0cf9c --- /dev/null +++ b/code/controllers/Processes/mob.dm @@ -0,0 +1,20 @@ +/datum/controller/process/mob + var/tmp/datum/updateQueue/updateQueueInstance + +/datum/controller/process/mob/setup() + name = "mob" + schedule_interval = 20 // every 2 seconds + updateQueueInstance = new + +/datum/controller/process/mob/started() + ..() + if(!updateQueueInstance) + if(!mob_list) + mob_list = list() + else if(mob_list.len) + updateQueueInstance = new + +/datum/controller/process/mob/doWork() + if(updateQueueInstance) + updateQueueInstance.init(mob_list, "Life") + updateQueueInstance.Run() diff --git a/code/controllers/Processes/nanoui.dm b/code/controllers/Processes/nanoui.dm new file mode 100644 index 00000000000..c8396bcab87 --- /dev/null +++ b/code/controllers/Processes/nanoui.dm @@ -0,0 +1,11 @@ +/datum/controller/process/nanoui + var/tmp/datum/updateQueue/updateQueueInstance + +/datum/controller/process/nanoui/setup() + name = "nanoui" + schedule_interval = 20 // every 2 seconds + updateQueueInstance = new + +/datum/controller/process/nanoui/doWork() + updateQueueInstance.init(nanomanager.processing_uis, "process") + updateQueueInstance.Run() diff --git a/code/controllers/Processes/obj.dm b/code/controllers/Processes/obj.dm new file mode 100644 index 00000000000..15ad98dd3d6 --- /dev/null +++ b/code/controllers/Processes/obj.dm @@ -0,0 +1,21 @@ +var/global/list/object_profiling = list() +/datum/controller/process/obj + var/tmp/datum/updateQueue/updateQueueInstance + +/datum/controller/process/obj/setup() + name = "obj" + schedule_interval = 20 // every 2 seconds + updateQueueInstance = new + +/datum/controller/process/obj/started() + ..() + if(!updateQueueInstance) + if(!processing_objects) + processing_objects = list() + else if(processing_objects.len) + updateQueueInstance = new + +/datum/controller/process/obj/doWork() + if(updateQueueInstance) + updateQueueInstance.init(processing_objects, "process") + updateQueueInstance.Run() diff --git a/code/controllers/Processes/pipenet.dm b/code/controllers/Processes/pipenet.dm new file mode 100644 index 00000000000..56a068f54ca --- /dev/null +++ b/code/controllers/Processes/pipenet.dm @@ -0,0 +1,12 @@ +/datum/controller/process/pipenet/setup() + name = "pipenet" + schedule_interval = 20 // every 2 seconds + +/datum/controller/process/pipenet/doWork() + for(var/datum/pipe_network/pipeNetwork in pipe_networks) + if(istype(pipeNetwork) && !pipeNetwork.disposed) + pipeNetwork.process() + scheck() + continue + + pipe_networks.Remove(pipeNetwork) diff --git a/code/controllers/Processes/power_machinery.dm b/code/controllers/Processes/power_machinery.dm new file mode 100644 index 00000000000..ce17c0583a6 --- /dev/null +++ b/code/controllers/Processes/power_machinery.dm @@ -0,0 +1,45 @@ +var/global/list/power_machinery_profiling = list() + +/datum/controller/process/power_machinery + var/tmp/datum/updateQueue/updateQueueInstance + +/datum/controller/process/power_machinery/setup() + name = "pow_machine" + schedule_interval = 20 // every 2 seconds + +/datum/controller/process/power_machinery/doWork() + for(var/i = 1 to power_machines.len) + if(i > power_machines.len) + break + var/obj/machinery/M = power_machines[i] + if(istype(M) && !M.gcDestroyed) + #ifdef PROFILE_MACHINES + var/time_start = world.timeofday + #endif + + if(M.process() == PROCESS_KILL) + M.inMachineList = 0 + power_machines.Remove(M) + continue + + if(M && M.use_power) + M.auto_use_power() + if(istype(M)) + #ifdef PROFILE_MACHINES + var/time_end = world.timeofday + + if(!(M.type in power_machinery_profiling)) + power_machinery_profiling[M.type] = 0 + + power_machinery_profiling[M.type] += (time_end - time_start) + #endif + else + if(!power_machines.Remove(M)) + power_machines.Cut(i,i+1) + else + if(M) + M.inMachineList = 0 + if(!power_machines.Remove(M)) + power_machines.Cut(i,i+1) + + scheck() diff --git a/code/controllers/Processes/powernet.dm b/code/controllers/Processes/powernet.dm new file mode 100644 index 00000000000..1edf194915a --- /dev/null +++ b/code/controllers/Processes/powernet.dm @@ -0,0 +1,12 @@ +/datum/controller/process/powernet/setup() + name = "powernet" + schedule_interval = 20 // every 2 seconds + +/datum/controller/process/powernet/doWork() + for(var/datum/powernet/powerNetwork in powernets) + if(istype(powerNetwork) && !powerNetwork.disposed) + powerNetwork.reset() + scheck() + continue + + powernets.Remove(powerNetwork) diff --git a/code/controllers/Processes/shuttle.dm b/code/controllers/Processes/shuttle.dm new file mode 100644 index 00000000000..a10586d76d9 --- /dev/null +++ b/code/controllers/Processes/shuttle.dm @@ -0,0 +1,9 @@ +/datum/controller/process/Shuttle/setup() + name = "shuttle controller" + schedule_interval = 20 // every 2 seconds + + if(!shuttle_controller) + shuttle_controller = new + +/datum/controller/process/Shuttle/doWork() + shuttle_controller.process() diff --git a/code/controllers/Processes/sun.dm b/code/controllers/Processes/sun.dm new file mode 100644 index 00000000000..f09806cef53 --- /dev/null +++ b/code/controllers/Processes/sun.dm @@ -0,0 +1,7 @@ +/datum/controller/process/sun/setup() + name = "sun" + schedule_interval = 20 // every second + sun = new + +/datum/controller/process/sun/doWork() + sun.calc_position() diff --git a/code/controllers/Processes/supply.dm b/code/controllers/Processes/supply.dm new file mode 100644 index 00000000000..891a511ec6d --- /dev/null +++ b/code/controllers/Processes/supply.dm @@ -0,0 +1,6 @@ +/datum/controller/process/supply/setup() + name = "supply controller" + schedule_interval = 300 // every 30 seconds + +/datum/controller/process/supply/doWork() + supply_controller.process() \ No newline at end of file diff --git a/code/controllers/Processes/ticker.dm b/code/controllers/Processes/ticker.dm new file mode 100644 index 00000000000..b7c45ba91a4 --- /dev/null +++ b/code/controllers/Processes/ticker.dm @@ -0,0 +1,35 @@ +var/global/datum/controller/process/ticker/tickerProcess + +/datum/controller/process/ticker + var/lastTickerTimeDuration + var/lastTickerTime + +/datum/controller/process/ticker/setup() + name = "ticker" + schedule_interval = 20 // every 2 seconds + + lastTickerTime = world.timeofday + + if(!ticker) + ticker = new + + tickerProcess = src + + spawn(0) + if(ticker) + ticker.pregame() + +/datum/controller/process/ticker/doWork() + var/currentTime = world.timeofday + + if(currentTime < lastTickerTime) // check for midnight rollover + lastTickerTimeDuration = (currentTime - (lastTickerTime - TICKS_IN_DAY)) / TICKS_IN_SECOND + else + lastTickerTimeDuration = (currentTime - lastTickerTime) / TICKS_IN_SECOND + + lastTickerTime = currentTime + + ticker.process() + +/datum/controller/process/ticker/proc/getLastTickerTimeDuration() + return lastTickerTimeDuration diff --git a/code/controllers/Processes/vote.dm b/code/controllers/Processes/vote.dm new file mode 100644 index 00000000000..5df5ce69792 --- /dev/null +++ b/code/controllers/Processes/vote.dm @@ -0,0 +1,6 @@ +/datum/controller/process/vote/setup() + name = "vote" + schedule_interval = 10 // every second + +/datum/controller/process/vote/doWork() + vote.process() diff --git a/code/controllers/_DynamicAreaLighting_TG.dm b/code/controllers/_DynamicAreaLighting_TG.dm index 8168ef50aad..7ed1a047a0d 100644 --- a/code/controllers/_DynamicAreaLighting_TG.dm +++ b/code/controllers/_DynamicAreaLighting_TG.dm @@ -94,7 +94,7 @@ datum/light_source if(owner.loc && owner.luminosity > 0) readrgb(owner.l_color) effect = list() - for(var/turf/T in view(owner.get_light_range(),owner)) + for(var/turf/T in view(owner.get_light_range(),get_turf(owner))) var/delta_lumen = lum(T) if(delta_lumen > 0) effect[T] = delta_lumen @@ -160,14 +160,6 @@ atom/movable/New() trueLuminosity = luminosity * luminosity light = new(src) -//Objects with opacity will trigger nearby lights to update at next lighting process. -atom/movable/Destroy() - if(opacity) - if(isturf(loc)) - if(loc:lighting_lumcount > 1) - UpdateAffectingLights() - - ..() //Sets our luminosity. //If we have no light it will create one. diff --git a/code/controllers/communications.dm b/code/controllers/communications.dm index b3a5a9f58d1..6fc3faab894 100644 --- a/code/controllers/communications.dm +++ b/code/controllers/communications.dm @@ -40,7 +40,7 @@ obj/proc/receive_signal(datum/signal/signal, var/receive_method as num, var/receive_param) Handler from received signals. By default does nothing. Define your own for your object. - Avoid of sending signals directly from this proc, use spawn(-1). Do not use sleep() here please. + Avoid of sending signals directly from this proc, use spawn(-1). DO NOT use sleep() here or call procs that sleep please. If you must, use spawn() parameters: signal - see description below. Extract all needed data from the signal before doing sleep(), spawn() or return! receive_method - may be TRANSMISSION_WIRE or TRANSMISSION_RADIO. @@ -61,33 +61,6 @@ */ -/* the radio controller is a confusing piece of shit and didnt work - so i made radios not use the radio controller. -*/ -var/list/all_radios = list() - -/proc/add_radio(var/obj/item/radio, freq) - if(!freq || !radio) - return - if(!all_radios["[freq]"]) - all_radios["[freq]"] = list(radio) - return freq - - all_radios["[freq]"] |= radio - return freq - -/proc/remove_radio(var/obj/item/radio, freq) - if(!freq || !radio) - return - if(!all_radios["[freq]"]) - return - - all_radios["[freq]"] -= radio - -/proc/remove_radio_all(var/obj/item/radio) - for(var/freq in all_radios) - all_radios["[freq]"] -= radio - /* Frequency range: 1200 to 1600 Radiochat range: 1441 to 1489 (most devices refuse to be tune to other frequency, even during mapmaking) @@ -99,10 +72,10 @@ Radio: 1355 - Medical 1357 - Engineering 1359 - Security -1441 - death squad +1341 - death squad 1443 - Confession Intercom 1347 - Cargo techs -1349 - Service +1349 - Service people Devices: 1451 - tracking implant @@ -112,7 +85,7 @@ On the map: 1311 for prison shuttle console (in fact, it is not used) 1435 for status displays 1437 for atmospherics/fire alerts -1439 for engine components +1438 for engine components 1439 for air pumps, air scrubbers, atmo control 1441 for atmospherics - supply tanks 1443 for atmospherics - distribution loop/mixed air tank @@ -124,30 +97,14 @@ On the map: 1455 for AI access */ -var/list/radiochannels = list( - "Common" = 1459, - "Science" = 1351, - "Command" = 1353, - "Medical" = 1355, - "Engineering" = 1357, - "Security" = 1359, - "Response Team" = 1443, - "Deathsquad" = 1441, - "Syndicate" = 1213, - "Supply" = 1347, - "Service" = 1349, - "AI Private" = 1447 -) -//depenging helpers -var/list/DEPT_FREQS = list(1351, 1355, 1357, 1359, 1213, 1443, 1441, 1347, 1349) - -// central command channels, i.e deathsquid & response teams -var/list/CENT_FREQS = list(1441, 1443) - -var/const/COMM_FREQ = 1353 //command, colored gold in chat window +var/const/COMM_FREQ = 1353 var/const/SYND_FREQ = 1213 +var/const/ERT_FREQ = 1345 +var/const/DTH_FREQ = 1341 +var/const/AI_FREQ = 1447 // department channels +var/const/PUB_FREQ = 1459 var/const/SEC_FREQ = 1359 var/const/ENG_FREQ = 1357 var/const/SCI_FREQ = 1351 @@ -155,25 +112,85 @@ var/const/MED_FREQ = 1355 var/const/SUP_FREQ = 1347 var/const/SRV_FREQ = 1349 -// other channels -var/const/AIPRIV_FREQ = 1447 +var/list/radiochannels = list( + "Common" = PUB_FREQ, + "Science" = SCI_FREQ, + "Command" = COMM_FREQ, + "Medical" = MED_FREQ, + "Engineering" = ENG_FREQ, + "Security" = SEC_FREQ, + "Response Team" = ERT_FREQ, + "Special Ops" = DTH_FREQ, + "Syndicate" = SYND_FREQ, + "Supply" = SUP_FREQ, + "Service" = SRV_FREQ, + "AI Private" = AI_FREQ +) + +// central command channels, i.e deathsquid & response teams +var/list/CENT_FREQS = list(ERT_FREQ, DTH_FREQ) + +// Antag channels, i.e. Syndicate +var/list/ANTAG_FREQS = list(SYND_FREQ) + +//depenging helpers +var/list/DEPT_FREQS = list(SCI_FREQ, MED_FREQ, ENG_FREQ, SEC_FREQ, SUP_FREQ, SRV_FREQ, ERT_FREQ, SYND_FREQ, DTH_FREQ) #define TRANSMISSION_WIRE 0 #define TRANSMISSION_RADIO 1 +/proc/frequency_span_class(var/frequency) + // Antags! + if (frequency in ANTAG_FREQS) + return "syndradio" + // centcomm channels (deathsquid and ert) + else if(frequency in CENT_FREQS) + return "centradio" + // command channel + else if(frequency == COMM_FREQ) + return "comradio" + // AI private channel + else if(frequency == AI_FREQ) + return "airadio" + // department radio formatting (poorly optimized, ugh) + else if(frequency == SEC_FREQ) + return "secradio" + else if (frequency == ENG_FREQ) + return "engradio" + else if(frequency == SCI_FREQ) + return "sciradio" + else if(frequency == MED_FREQ) + return "medradio" + else if(frequency == SUP_FREQ) // cargo + return "supradio" + else if(frequency == SRV_FREQ) // service + return "srvradio" + // If all else fails and it's a dept_freq, color me purple! + else if(frequency in DEPT_FREQS) + return "deptradio" + + return "radio" + /* filters */ -var/const/RADIO_TO_AIRALARM = "1" -var/const/RADIO_FROM_AIRALARM = "2" -var/const/RADIO_CHAT = "3" -var/const/RADIO_ATMOSIA = "4" -var/const/RADIO_NAVBEACONS = "5" -var/const/RADIO_AIRLOCK = "6" -var/const/RADIO_SECBOT = "7" -var/const/RADIO_MULEBOT = "8" -var/const/RADIO_MAGNETS = "9" +//When devices register with the radio controller, they might register under a certain filter. +//Other devices can then choose to send signals to only those devices that belong to a particular filter. +//This is done for performance, so we don't send signals to lots of machines unnecessarily. + +//This filter is special because devices belonging to default also recieve signals sent to any other filter. +var/const/RADIO_DEFAULT = "radio_default" + +var/const/RADIO_TO_AIRALARM = "radio_airalarm" //air alarms +var/const/RADIO_FROM_AIRALARM = "radio_airalarm_rcvr" //devices interested in recieving signals from air alarms +var/const/RADIO_CHAT = "radio_telecoms" +var/const/RADIO_ATMOSIA = "radio_atmos" +var/const/RADIO_NAVBEACONS = "radio_navbeacon" +var/const/RADIO_AIRLOCK = "radio_airlock" +var/const/RADIO_SECBOT = "radio_secbot" +var/const/RADIO_MULEBOT = "radio_mulebot" var/const/RADIO_CLEANBOT = "10" var/const/RADIO_FLOORBOT = "11" var/const/RADIO_MEDBOT = "12" +var/const/RADIO_MAGNETS = "radio_magnet" var/global/datum/controller/radio/radio_controller @@ -181,164 +198,138 @@ var/global/datum/controller/radio/radio_controller radio_controller = new /datum/controller/radio() return 1 -datum/controller/radio +//callback used by objects to react to incoming radio signals +/obj/proc/receive_signal(datum/signal/signal, receive_method, receive_param) + return null + +//The global radio controller +/datum/controller/radio var/list/datum/radio_frequency/frequencies = list() - proc/add_object(obj/device as obj, var/new_frequency as num, var/filter = null as text|null) - var/f_text = num2text(new_frequency) - var/datum/radio_frequency/frequency = frequencies[f_text] +/datum/controller/radio/proc/add_object(obj/device as obj, var/new_frequency as num, var/filter = null as text|null) + var/f_text = num2text(new_frequency) + var/datum/radio_frequency/frequency = frequencies[f_text] - if(!frequency) - frequency = new - frequency.frequency = new_frequency - frequencies[f_text] = frequency + if(!frequency) + frequency = new + frequency.frequency = new_frequency + frequencies[f_text] = frequency - frequency.add_listener(device, filter) - return frequency + frequency.add_listener(device, filter) + return frequency - proc/remove_object(obj/device, old_frequency) - var/f_text = num2text(old_frequency) - var/datum/radio_frequency/frequency = frequencies[f_text] +/datum/controller/radio/proc/remove_object(obj/device, old_frequency) + var/f_text = num2text(old_frequency) + var/datum/radio_frequency/frequency = frequencies[f_text] - if(frequency) - frequency.remove_listener(device) + if(frequency) + frequency.remove_listener(device) - if(frequency.devices.len == 0) - del(frequency) - frequencies -= f_text + if(frequency.devices.len == 0) + del(frequency) + frequencies -= f_text - return 1 + return 1 - proc/return_frequency(var/new_frequency as num) - var/f_text = num2text(new_frequency) - var/datum/radio_frequency/frequency = frequencies[f_text] +/datum/controller/radio/proc/return_frequency(var/new_frequency as num) + var/f_text = num2text(new_frequency) + var/datum/radio_frequency/frequency = frequencies[f_text] - if(!frequency) - frequency = new - frequency.frequency = new_frequency - frequencies[f_text] = frequency + if(!frequency) + frequency = new + frequency.frequency = new_frequency + frequencies[f_text] = frequency - return frequency + return frequency -datum/radio_frequency +/datum/radio_frequency var/frequency as num var/list/list/obj/devices = list() - proc - post_signal(obj/source as obj|null, datum/signal/signal, var/filter = null as text|null, var/range = null as num|null) - //log_admin("DEBUG \[[world.timeofday]\]: post_signal {source=\"[source]\", [signal.debug_print()], filter=[filter]}") -// var/N_f=0 -// var/N_nf=0 -// var/Nt=0 - var/turf/start_point - if(range) - start_point = get_turf(source) - if(!start_point) - del(signal) - return 0 - if (filter) //here goes some copypasta. It is for optimisation. -rastaf0 - for(var/obj/device in devices[filter]) - if(device == source) - continue - if(range) - var/turf/end_point = get_turf(device) - if(!end_point) - continue - //if(max(abs(start_point.x-end_point.x), abs(start_point.y-end_point.y)) <= range) - if(start_point.z!=end_point.z || get_dist(start_point, end_point) > range) - continue - device.receive_signal(signal, TRANSMISSION_RADIO, frequency) - for(var/obj/device in devices["_default"]) - if(device == source) - continue - if(range) - var/turf/end_point = get_turf(device) - if(!end_point) - continue - //if(max(abs(start_point.x-end_point.x), abs(start_point.y-end_point.y)) <= range) - if(start_point.z!=end_point.z || get_dist(start_point, end_point) > range) - continue - device.receive_signal(signal, TRANSMISSION_RADIO, frequency) -// N_f++ - else - for (var/next_filter in devices) -// var/list/obj/DDD = devices[next_filter] -// Nt+=DDD.len - for(var/obj/device in devices[next_filter]) - if(device == source) - continue - if(range) - var/turf/end_point = get_turf(device) - if(!end_point) - continue - //if(max(abs(start_point.x-end_point.x), abs(start_point.y-end_point.y)) <= range) - if(start_point.z!=end_point.z || get_dist(start_point, end_point) > range) - continue - device.receive_signal(signal, TRANSMISSION_RADIO, frequency) -// N_nf++ +/datum/radio_frequency/proc/post_signal(obj/source as obj|null, datum/signal/signal, var/filter = null as text|null, var/range = null as num|null) + var/turf/start_point + if(range) + start_point = get_turf(source) + if(!start_point) + del(signal) + return 0 + if (filter) + send_to_filter(source, signal, filter, start_point, range) + send_to_filter(source, signal, RADIO_DEFAULT, start_point, range) + else + //Broadcast the signal to everyone! + for (var/next_filter in devices) + send_to_filter(source, signal, next_filter, start_point, range) -// log_admin("DEBUG: post_signal(source=[source] ([source.x], [source.y], [source.z]),filter=[filter]) frequency=[frequency], N_f=[N_f], N_nf=[N_nf]") +//Sends a signal to all machines belonging to a given filter. Should be called by post_signal() +/datum/radio_frequency/proc/send_to_filter(obj/source, datum/signal/signal, var/filter, var/turf/start_point = null, var/range = null) + if (range && !start_point) + return + for(var/obj/device in devices[filter]) + if(device == source) + continue + if(range) + var/turf/end_point = get_turf(device) + if(!end_point) + continue + if(start_point.z!=end_point.z || get_dist(start_point, end_point) > range) + continue -// del(signal) + device.receive_signal(signal, TRANSMISSION_RADIO, frequency) - add_listener(obj/device as obj, var/filter as text|null) - if (!filter) - filter = "_default" - //log_admin("add_listener(device=[device],filter=[filter]) frequency=[frequency]") - var/list/obj/devices_line = devices[filter] - if (!devices_line) - devices_line = new - devices[filter] = devices_line - devices_line+=device +/datum/radio_frequency/proc/add_listener(obj/device as obj, var/filter as text|null) + if (!filter) + filter = RADIO_DEFAULT + //log_admin("add_listener(device=[device],filter=[filter]) frequency=[frequency]") + var/list/obj/devices_line = devices[filter] + if (!devices_line) + devices_line = new + devices[filter] = devices_line + devices_line+=device // var/list/obj/devices_line___ = devices[filter_str] // var/l = devices_line___.len - //log_admin("DEBUG: devices_line.len=[devices_line.len]") - //log_admin("DEBUG: devices(filter_str).len=[l]") + //log_admin("DEBUG: devices_line.len=[devices_line.len]") + //log_admin("DEBUG: devices(filter_str).len=[l]") - remove_listener(obj/device) - for (var/devices_filter in devices) - var/list/devices_line = devices[devices_filter] - devices_line-=device - while (null in devices_line) - devices_line -= null - if (devices_line.len==0) - devices -= devices_filter - del(devices_line) +/datum/radio_frequency/proc/remove_listener(obj/device) + for (var/devices_filter in devices) + var/list/devices_line = devices[devices_filter] + devices_line-=device + while (null in devices_line) + devices_line -= null + if (devices_line.len==0) + devices -= devices_filter + del(devices_line) - -obj/proc - receive_signal(datum/signal/signal, receive_method, receive_param) - return null - -datum/signal +/datum/signal var/obj/source - var/transmission_method = 0 + var/transmission_method = 0 //unused at the moment //0 = wire //1 = radio transmission //2 = subspace transmission - var/data = list() + var/list/data = list() var/encryption var/frequency = 0 - proc/copy_from(datum/signal/model) - source = model.source - transmission_method = model.transmission_method - data = model.data - encryption = model.encryption - frequency = model.frequency +/datum/signal/proc/copy_from(datum/signal/model) + source = model.source + transmission_method = model.transmission_method + data = model.data + encryption = model.encryption + frequency = model.frequency - proc/debug_print() - if (source) - . = "signal = {source = '[source]' ([source:x],[source:y],[source:z])\n" - else - . = "signal = {source = '[source]' ()\n" - for (var/i in data) - . += "data\[\"[i]\"\] = \"[data[i]]\"\n" - if(islist(data[i])) - var/list/L = data[i] - for(var/t in L) - . += "data\[\"[i]\"\] list has: [t]" +/datum/signal/proc/debug_print() + if (source) + . = "signal = {source = '[source]' ([source:x],[source:y],[source:z])\n" + else + . = "signal = {source = '[source]' ()\n" + for (var/i in data) + . += "data\[\"[i]\"\] = \"[data[i]]\"\n" + if(islist(data[i])) + var/list/L = data[i] + for(var/t in L) + . += "data\[\"[i]\"\] list has: [t]" diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 5806da2e51a..95ecef88978 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -134,7 +134,12 @@ var/python_path = "" //Path to the python executable. Defaults to "python" on windows and "/usr/bin/env python2" on unix var/default_laws = 0 //Controls what laws the AI spawns with. - + + var/list/station_levels = list(1) // Defines which Z-levels the station exists on. + var/list/admin_levels= list(2) // Defines which Z-levels which are for admin functionality, for example including such areas as Central Command and the Syndicate Shuttle + var/list/contact_levels = list(1, 5) // Defines which Z-levels which, for example, a Code Red announcement may affect + var/list/player_levels = list(1, 3, 4, 5, 6, 7) // Defines all Z-levels a character can typically reach + var/const/minutes_to_ticks = 60 * 10 // Event settings var/expected_round_length = 60 * 2 * minutes_to_ticks // 2 hours @@ -163,7 +168,7 @@ src.probabilities[M.config_tag] = M.probability if (M.votable) src.votable_modes += M.config_tag - del(M) + qdel(M) src.votable_modes += "secret" /datum/configuration/proc/load(filename, type = "config") //the type can also be game_options, in which case it uses a different switch. not making it separate to not copypaste code - Urist @@ -204,9 +209,9 @@ if ("use_age_restriction_for_jobs") config.use_age_restriction_for_jobs = 1 - + if ("use_age_restriction_for_antags") - config.use_age_restriction_for_antags = 1 + config.use_age_restriction_for_antags = 1 if ("jobs_have_minimal_access") config.jobs_have_minimal_access = 1 @@ -457,7 +462,19 @@ if("max_maint_drones") config.max_maint_drones = text2num(value) - + + if("station_levels") + config.station_levels = text2numlist(value, ";") + + if("admin_levels") + config.admin_levels = text2numlist(value, ";") + + if("contact_levels") + config.contact_levels = text2numlist(value, ";") + + if("player_levels") + config.player_levels = text2numlist(value, ";") + if("expected_round_length") config.expected_round_length = MinutesToTicks(text2num(value)) diff --git a/code/controllers/emergency_shuttle_controller.dm b/code/controllers/emergency_shuttle_controller.dm index 55b325eba3c..83a9d379434 100644 --- a/code/controllers/emergency_shuttle_controller.dm +++ b/code/controllers/emergency_shuttle_controller.dm @@ -18,7 +18,10 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle var/deny_shuttle = 0 //allows admins to prevent the shuttle from being called var/departed = 0 //if the shuttle has left the station at least once - + + var/datum/announcement/priority/emergency_shuttle_docked = new(0, new_sound = sound('sound/AI/shuttledock.ogg')) + var/datum/announcement/priority/emergency_shuttle_called = new(0, new_sound = sound('sound/AI/shuttlecalled.ogg')) + var/datum/announcement/priority/emergency_shuttle_recalled = new(0, new_sound = sound('sound/AI/shuttlerecalled.ogg')) /datum/emergency_shuttle_controller/proc/process() if (wait_for_launch) @@ -29,7 +32,7 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle if (!shuttle.location) //leaving from the station if(is_stranded()) - captain_announce("Hostile environment detected. Departure has been postponed indefinitely pending conflict resolution.") + priority_announcement.Announce("Hostile environment detected. Departure has been postponed indefinitely pending conflict resolution.") wait_for_launch = 0 return //launch the pods! @@ -49,10 +52,9 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle set_launch_countdown(SHUTTLE_LEAVETIME) //get ready to return if (evac) - captain_announce("The Emergency Shuttle has docked with the station. You have approximately [round(estimate_launch_time()/60,1)] minutes to board the Emergency Shuttle.") - world << sound('sound/AI/shuttledock.ogg') + emergency_shuttle_docked.Announce("The Emergency Shuttle has docked with the station. You have approximately [round(estimate_launch_time()/60,1)] minutes to board the Emergency Shuttle.") else - captain_announce("The scheduled Crew Transfer Shuttle has docked with the station. It will depart in approximately [round(emergency_shuttle.estimate_launch_time()/60,1)] minutes.") + priority_announcement.Announce("The scheduled Crew Transfer Shuttle has docked with the station. It will depart in approximately [round(emergency_shuttle.estimate_launch_time()/60,1)] minutes.") //arm the escape pods if (evac) @@ -81,8 +83,7 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle shuttle.move_time = SHUTTLE_TRANSIT_DURATION evac = 1 - captain_announce("An emergency evacuation shuttle has been called. It will arrive in approximately [round(estimate_arrival_time()/60)] minutes.") - world << sound('sound/AI/shuttlecalled.ogg') + emergency_shuttle_called.Announce("An emergency evacuation shuttle has been called. It will arrive in approximately [round(estimate_arrival_time()/60)] minutes.") for(var/area/A in world) if(istype(A, /area/hallway)) A.readyalert() @@ -101,7 +102,7 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle //reset the shuttle transit time if we need to shuttle.move_time = SHUTTLE_TRANSIT_DURATION - captain_announce("A crew transfer has been scheduled. The shuttle has been called. It will arrive in approximately [round(estimate_arrival_time()/60)] minutes.") + priority_announcement.Announce("A crew transfer has been scheduled. The shuttle has been called. It will arrive in approximately [round(estimate_arrival_time()/60)] minutes.") //recalls the shuttle /datum/emergency_shuttle_controller/proc/recall() @@ -111,15 +112,14 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle shuttle.cancel_launch(src) if (evac) - captain_announce("The emergency shuttle has been recalled.") - world << sound('sound/AI/shuttlerecalled.ogg') + emergency_shuttle_recalled.Announce("The emergency shuttle has been recalled.") for(var/area/A in world) if(istype(A, /area/hallway)) A.readyreset() evac = 0 else - captain_announce("The scheduled crew transfer has been cancelled.") + priority_announcement.Announce("The scheduled crew transfer has been cancelled.") /datum/emergency_shuttle_controller/proc/can_call() if (deny_shuttle) diff --git a/code/controllers/failsafe.dm b/code/controllers/failsafe.dm index ff46b6b10b6..a2a6274a8ab 100644 --- a/code/controllers/failsafe.dm +++ b/code/controllers/failsafe.dm @@ -1,68 +1,78 @@ -var/datum/controller/failsafe/Failsafe +var/global/datum/controller/failsafe/failsafe -/datum/controller/failsafe // This thing pretty much just keeps poking the master controller - var/processing = 0 - var/processing_interval = 100 //poke the MC every 10 seconds +/datum/controller/failsafe // This thing pretty much just keeps poking the controllers. + processing_interval = 100 // Poke the controllers every 10 seconds. - var/MC_iteration = 0 - var/MC_defcon = 0 //alert level. For every poke that fails this is raised by 1. When it reaches 5 the MC is replaced with a new one. (effectively killing any master_controller.process() and starting a new one) + /* + * Controller alert level. + * For every poke that fails this is raised by 1. + * When it reaches 5 the MC is replaced with a new one + * (effectively killing any controller process() and starting a new one). + */ - var/lighting_iteration = 0 - var/lighting_defcon = 0 //alert level for lighting controller. + // master + var/masterControllerIteration = 0 + var/masterControllerAlertLevel = 0 + + // lighting + var/lightingControllerIteration = 0 + var/lightingControllerAlertLevel = 0 /datum/controller/failsafe/New() - //There can be only one failsafe. Out with the old in with the new (that way we can restart the Failsafe by spawning a new one) - if(Failsafe != src) - if(istype(Failsafe)) - del(Failsafe) - Failsafe = src - Failsafe.process() + . = ..() + // There can be only one failsafe. Out with the old in with the new (that way we can restart the Failsafe by spawning a new one). + if (failsafe != src) + if (istype(failsafe)) + recover() + qdel(failsafe) + + failsafe = src + + failsafe.process() /datum/controller/failsafe/proc/process() processing = 1 + spawn(0) - //set background = 1 - while(1) //more efficient than recursivly calling ourself over and over. background = 1 ensures we do not trigger an infinite loop - if(!master_controller) new /datum/controller/game_controller() //replace the missing master_controller! This should never happen. - if(!lighting_controller) new /datum/controller/lighting() //replace the missing lighting_controller + set background = BACKGROUND_ENABLED + + while(1) // More efficient than recursivly calling ourself over and over. background = 1 ensures we do not trigger an infinite loop. + iteration++ if(processing) - if(master_controller.processing) //only poke if these overrides aren't in effect - if(MC_iteration == controller_iteration) //master_controller hasn't finished processing in the defined interval - switch(MC_defcon) + if(master_controller.processing) // Only poke if these overrides aren't in effect + if(masterControllerIteration == master_controller.iteration) // Master controller hasn't finished processing in the defined interval. + switch(masterControllerAlertLevel) if(0 to 3) - MC_defcon++ + masterControllerAlertLevel++ if(4) - admins << "Warning. The Master Controller has not fired in the last [MC_defcon*processing_interval] ticks. Automatic restart in [processing_interval] ticks." - MC_defcon = 5 + admins << "Warning. The master Controller has not fired in the last [masterControllerAlertLevel * processing_interval] ticks. Automatic restart in [processing_interval] ticks." + masterControllerAlertLevel = 5 if(5) - admins << "Warning. The Master Controller has still not fired within the last [MC_defcon*processing_interval] ticks. Killing and restarting..." - new /datum/controller/game_controller() //replace the old master_controller (hence killing the old one's process) - master_controller.process() //Start it rolling again - MC_defcon = 0 + admins << "Warning. The master Controller has still not fired within the last [masterControllerAlertLevel * processing_interval] ticks. Killing and restarting..." + new /datum/controller/game_controller() // Replace the old master controller (hence killing the old one's process). + master_controller.process() // Start it rolling again. + masterControllerAlertLevel = 0 else - MC_defcon = 0 - MC_iteration = controller_iteration + masterControllerAlertLevel = 0 + masterControllerIteration = master_controller.iteration if(lighting_controller.processing) - if(lighting_iteration == lighting_controller.iteration) //master_controller hasn't finished processing in the defined interval - switch(lighting_defcon) + if(lightingControllerIteration == lighting_controller.iteration) // Lighting controller hasn't finished processing in the defined interval. + switch(lightingControllerAlertLevel) if(0 to 3) - lighting_defcon++ + lightingControllerAlertLevel++ if(4) - admins << "Warning. The Lighting Controller has not fired in the last [lighting_defcon*processing_interval] ticks. Automatic restart in [processing_interval] ticks." - lighting_defcon = 5 + admins << "Warning. The lighting_controller controller has not fired in the last [lightingControllerAlertLevel * processing_interval] ticks. Automatic restart in [processing_interval] ticks." + lightingControllerAlertLevel = 5 if(5) - admins << "Warning. The Lighting Controller has still not fired within the last [lighting_defcon*processing_interval] ticks. Killing and restarting..." - new /datum/controller/lighting() //replace the old lighting_controller (hence killing the old one's process) - lighting_controller.process() //Start it rolling again - lighting_defcon = 0 + admins << "Warning. The lighting_controller controller has still not fired within the last [lightingControllerAlertLevel * processing_interval] ticks. Killing and restarting..." + new /datum/controller/lighting() // Replace the old lighting_controller (hence killing the old one's process). + lighting_controller.process() // Start it rolling again. + lightingControllerAlertLevel = 0 else - lighting_defcon = 0 - lighting_iteration = lighting_controller.iteration - else - MC_defcon = 0 - lighting_defcon = 0 + lightingControllerAlertLevel = 0 + lightingControllerIteration = lighting_controller.iteration - sleep(processing_interval) \ No newline at end of file + sleep(processing_interval) diff --git a/code/controllers/garbage.dm b/code/controllers/garbage.dm index 412a4bdef10..3c96126c0f1 100644 --- a/code/controllers/garbage.dm +++ b/code/controllers/garbage.dm @@ -1,124 +1,186 @@ +#define GC_COLLECTIONS_PER_TICK 300 // Was 100. +#define GC_COLLECTION_TIMEOUT (30 SECONDS) +#define GC_FORCE_DEL_PER_TICK 60 +//#define GC_DEBUG -#define GC_COLLECTIONS_PER_TICK 250 // Was 100 -#define GC_COLLECTION_TIMEOUT 100 // 10s -var/global/datum/controller/garbage_collector/garbage -var/global/list/uncollectable_vars=list( - "alpha", - "bestF", - "bounds", - "bound_height", - "bound_width", - "ckey", - "color", - "contents", - "gender", - "group", - "key", - //"loc", - "locs", - "luminosity", - "parent", - "parent_type", - "step_size", - "glide_size", - "gc_destroyed", - "step_x", - "step_y", - "step_z", - "tag", - "thermal_conductivity", - "type", - "vars", - "verbs", - "x", - "y", - "z", -) -/datum/controller/garbage_collector - var/list/queue=list() - var/list/destroyed=list() - var/waiting=0 - var/del_everything=1 - var/turf/trashbin=null +var/list/gc_hard_del_types = new +var/datum/garbage_collector/garbageCollector - New() - trashbin=locate(0,0,CENTCOMM_Z) +/client/proc/gc_dump_hdl() + set name = "(GC) Hard Del List" + set desc = "List types that are hard del()'d by the GC." + set category = "Debug" - proc/AddTrash(var/atom/movable/A) - if(!A) - return - if(del_everything) - del(A) - return - A.loc=trashbin - queue.Add(A) - waiting++ + for(var/A in gc_hard_del_types) + usr << "[A] = [gc_hard_del_types[A]]" - proc/Pop() - var/atom/movable/A = queue[1] - if(!A) - if(isnull(A)) - var/loopcheck = 0 - while(queue.Remove(null)) - loopcheck++ - if(loopcheck > 50) - break - return - if(del_everything) - del(A) - return - if(!istype(A,/atom/movable)) - testing("GC given a [A.type].") - del(A) - return - for(var/vname in A.vars) - if(!issaved(A.vars[vname])) - continue - if(vname in uncollectable_vars) - continue - //testing("Unsetting [vname] in [A.type]!") - A.vars[vname]=null - A.loc=null - destroyed.Add("\ref[A]") - queue.Remove(A) +/datum/garbage_collector + var/list/queue = new + var/del_everything = 0 - proc/process() - for(var/i=0;i= world.time - GC_COLLECTION_TIMEOUT) - // Something's still referring to the qdel'd object. Kill it. - del(A) - destroyed.Remove(refID) + // To let them know how hardworking am I :^). + var/dels_count = 0 + var/hard_dels = 0 + var/soft_dels = 0 -/** -* NEVER USE THIS FOR ANYTHING OTHER THAN /atom/movable -* OTHER TYPES CANNOT BE QDEL'D BECAUSE THEIR LOC IS LOCKED OR THEY DON'T HAVE ONE. -*/ -/proc/qdel(var/atom/movable/A) - if(!A) return - if(!istype(A)) - warning("qdel() passed object of type [A.type]. qdel() can only handle /atom/movable types.") - del(A) +/datum/garbage_collector/proc/addTrash(const/atom/movable/AM) + if(!istype(AM)) return - if(!garbage) - del(A) + + if(del_everything) + del(AM) + hard_dels++ + dels_count++ return - // Let our friend know they're about to get fucked up. - A.Destroy() - garbage.AddTrash(A) + + queue["\ref[AM]"] = world.timeofday + +/datum/garbage_collector/proc/process() + var/remainingCollectionPerTick = GC_COLLECTIONS_PER_TICK + var/remainingForceDelPerTick = GC_FORCE_DEL_PER_TICK + var/collectionTimeScope = world.timeofday - GC_COLLECTION_TIMEOUT + if(narsie_cometh) return //don't even fucking bother, its over. + while(queue.len && --remainingCollectionPerTick >= 0) + var/refID = queue[1] + var/destroyedAtTime = queue[refID] + + if(destroyedAtTime > collectionTimeScope) + break + + var/atom/movable/AM = locate(refID) + if(AM) // Something's still referring to the qdel'd object. del it. + if(isnull(AM.gcDestroyed)) + queue -= refID + continue + if(remainingForceDelPerTick <= 0) + break + + #ifdef GC_DEBUG + WARNING("gc process force delete [AM.type]") + #endif + + AM.hard_deleted = 1 + if(!AM.type in gc_hard_del_types) + gc_hard_del_types += AM.type + del AM + + hard_dels++ + remainingForceDelPerTick-- + +#ifdef GC_DEBUG +#undef GC_DEBUG +#endif + +#undef GC_FORCE_DEL_PER_TICK +#undef GC_COLLECTION_TIMEOUT +#undef GC_COLLECTIONS_PER_TICK + +/datum/garbage_collector/proc/dequeue(id) + if (queue) + queue -= id + + dels_count++ + +/* + * NEVER USE THIS FOR ANYTHING OTHER THAN /atom/movable + * OTHER TYPES CANNOT BE QDEL'D BECAUSE THEIR LOC IS LOCKED OR THEY DON'T HAVE ONE. + */ +/proc/qdel(const/atom/movable/AM, ignore_pooling = 0) + if(isnull(AM)) + return + + if(isnull(garbageCollector)) + del(AM) + return + + if(!istype(AM)) + WARNING("qdel() passed object of type [AM.type]. qdel() can only handle /atom/movable types.") + if(!AM.type in gc_hard_del_types) + gc_hard_del_types += AM.type + del(AM) + garbageCollector.hard_dels++ + garbageCollector.dels_count++ + return + + //We are object pooling this. + if(("[AM.type]" in masterPool) && !ignore_pooling) + returnToPool(AM) + return + + if(isnull(AM.gcDestroyed)) + // Let our friend know they're about to get fucked up. + AM.Destroy() + + garbageCollector.addTrash(AM) + +/datum/controller + var/processing = 0 + var/iteration = 0 + var/processing_interval = 0 + +/datum/controller/proc/recover() // If we are replacing an existing controller (due to a crash) we attempt to preserve as much as we can. + +/* + * Like Del(), but for qdel. + * Called BEFORE qdel moves shit. + */ +/datum/proc/Destroy() + del(src) /client/proc/qdel_toggle() set name = "Toggle qdel Behavior" set desc = "Toggle qdel usage between normal and force del()." set category = "Debug" - garbage.del_everything = !garbage.del_everything - world << "GC: qdel turned [garbage.del_everything?"off":"on"]." - log_admin("[key_name(usr)] turned qdel [garbage.del_everything?"off":"on"].") - message_admins("\blue [key_name(usr)] turned qdel [garbage.del_everything?"off":"on"].", 1) \ No newline at end of file + garbageCollector.del_everything = !garbageCollector.del_everything + world << "GC: qdel turned [garbageCollector.del_everything ? "off" : "on"]." + log_admin("[key_name(usr)] turned qdel [garbageCollector.del_everything ? "off" : "on"].") + message_admins("\blue [key_name(usr)] turned qdel [garbageCollector.del_everything ? "off" : "on"].", 1) + +/*/client/var/running_find_references + +/atom/verb/find_references() + set category = "Debug" + set name = "Find References" + set background = 1 + set src in world + + if(!usr || !usr.client) + return + + if(usr.client.running_find_references) + testing("CANCELLED search for references to a [usr.client.running_find_references].") + usr.client.running_find_references = null + return + + if(alert("Running this will create a lot of lag until it finishes. You can cancel it by running it again. Would you like to begin the search?", "Find References", "Yes", "No") == "No") + return + qdel(src) + // Remove this object from the list of things to be auto-deleted. + if(garbageCollector) + garbageCollector.queue -= "\ref[src]" + + usr.client.running_find_references = type + testing("Beginning search for references to a [type].") + var/list/things = list() + for(var/client/thing) + things += thing + for(var/datum/thing) + things += thing + for(var/atom/thing) + things += thing + for(var/event/thing) + things += thing + testing("Collected list of things in search for references to a [type]. ([things.len] Thing\s)") + for(var/datum/thing in things) + if(!usr.client.running_find_references) return + for(var/varname in thing.vars) + var/variable = thing.vars[varname] + if(variable == src) + testing("Found [src.type] \ref[src] in [thing.type]'s [varname] var.") + else if(islist(variable)) + if(src in variable) + testing("Found [src.type] \ref[src] in [thing.type]'s [varname] list var.") + testing("Completed search for references to a [type].") + usr.client.running_find_references = null +*/ \ No newline at end of file diff --git a/code/controllers/lighting_controller.dm b/code/controllers/lighting_controller.dm index c118fa43abb..a7decbc1185 100644 --- a/code/controllers/lighting_controller.dm +++ b/code/controllers/lighting_controller.dm @@ -1,10 +1,8 @@ var/datum/controller/lighting/lighting_controller = new () datum/controller/lighting - var/processing = 0 - var/processing_interval = 5 //setting this too low will probably kill the server. Don't be silly with it! + processing_interval = 5 //setting this too low will probably kill the server. Don't be silly with it! var/process_cost = 0 - var/iteration = 0 var/lighting_states = 7 @@ -21,7 +19,7 @@ datum/controller/lighting/New() if(lighting_controller != src) if(istype(lighting_controller,/datum/controller/lighting)) Recover() //if we are replacing an existing lighting_controller (due to a crash) we attempt to preserve as much as we can - del(lighting_controller) + qdel(lighting_controller) lighting_controller = src diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index 3aacb25c3fc..963e01b7260 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -5,14 +5,12 @@ var/global/datum/controller/game_controller/master_controller //Set in world.New() var/global/controller_iteration = 0 -var/global/last_tick_timeofday = world.timeofday var/global/last_tick_duration = 0 var/global/air_processing_killed = 0 var/global/pipe_processing_killed = 0 datum/controller/game_controller - var/processing = 0 var/breather_ticks = 2 //a somewhat crude attempt to iron over the 'bumps' caused by high-cpu use by letting the MC have a breather for this many ticks after every loop var/minimum_ticks = 20 //The minimum length of time between MC ticks @@ -29,7 +27,7 @@ datum/controller/game_controller var/events_cost = 0 var/puddles_cost var/ticker_cost = 0 - var/gc_cost = 0 + var/garbageCollectorCost = 0 var/total_cost = 0 var/last_thing_processed @@ -37,13 +35,14 @@ datum/controller/game_controller var/list/shuttle_list // For debugging and VV var/datum/ore_distribution/asteroid_ore_map // For debugging and VV. + var/global/datum/garbage_collector/garbageCollector datum/controller/game_controller/New() //There can be only one master_controller. Out with the old and in with the new. if(master_controller != src) if(istype(master_controller)) Recover() - del(master_controller) + qdel(master_controller) master_controller = src if(!job_master) @@ -54,8 +53,8 @@ datum/controller/game_controller/New() if(!syndicate_code_phrase) syndicate_code_phrase = generate_code_phrase() if(!syndicate_code_response) syndicate_code_response = generate_code_phrase() - if(!emergency_shuttle) emergency_shuttle = new /datum/emergency_shuttle_controller() - if(!shuttle_controller) shuttle_controller = new /datum/shuttle_controller() + //if(!emergency_shuttle) emergency_shuttle = new /datum/emergency_shuttle_controller() MOVED TO SCHEDULER + //if(!shuttle_controller) shuttle_controller = new /datum/shuttle_controller() datum/controller/game_controller/proc/setup() world.tick_lag = config.Ticklag @@ -63,15 +62,15 @@ datum/controller/game_controller/proc/setup() spawn(20) createRandomZlevel() + /* MOVED TO SCHEDULER if(!air_master) air_master = new /datum/controller/air_system() air_master.Setup() if(!ticker) ticker = new /datum/controller/gameticker() + */ - if(!garbage) - garbage = new /datum/controller/garbage_collector() color_windows_init() setup_objects() @@ -82,15 +81,17 @@ datum/controller/game_controller/proc/setup() for(var/i=0, i= R.reqs[A]) - continue main_loop - return 0 - for(var/A in R.chem_catalists) - if(holder_contents[A] < R.chem_catalists[A]) - return 0 - return 1 - -/datum/crafting_holder/proc/check_holder() - var/list/holder_contents = list() - for(var/obj/I in holder.loc) - if(istype(I, /obj/item/stack)) - var/obj/item/stack/S = I - holder_contents[I.type] += S.amount - else - if(istype(I, /obj/item/weapon/reagent_containers)) - for(var/datum/reagent/R in I.reagents.reagent_list) - holder_contents[R.type] += R.volume - - holder_contents[I.type] += 1 - - return holder_contents - -/datum/crafting_holder/proc/check_tools(mob/user, datum/crafting_recipe/R, list/holder_contents) - if(!R.tools.len) - return 1 - var/list/possible_tools = list() - for(var/obj/item/I in user.contents) - if(istype(I, /obj/item/weapon/storage)) - for(var/obj/item/SI in I.contents) - possible_tools += SI.type - else - possible_tools += I.type - possible_tools += holder_contents - var/i = R.tools.len - var/I - for(var/A in R.tools) - I = possible_tools.Find(A) - if(I) - possible_tools.Cut(I, I+1) - i-- - else - break - return !i - -/datum/crafting_holder/proc/construct_item(mob/user, datum/crafting_recipe/R) - var/list/holder_contents = check_holder() - if(check_contents(R, holder_contents) && check_tools(user, R, holder_contents)) - if(do_after(user, R.time)) - if(!check_contents(R, holder_contents) || !check_tools(user, R, holder_contents)) - return 0 - var/list/parts = del_reqs(R, holder_contents) - var/atom/movable/I = new R.result_path - for(var/A in parts) - if(istype(A, /obj/item)) - var/atom/movable/B = A - B.loc = I - else - if(!I.reagents) - I.reagents = new /datum/reagents() - I.reagents.reagent_list.Add(A) - I.CheckParts() - I.loc = holder.loc - return 1 - return 0 - -/datum/crafting_holder/proc/del_reqs(datum/crafting_recipe/R, list/holder_contents) - var/list/Deletion = list() - var/amt - for(var/A in R.reqs) - amt = R.reqs[A] - if(ispath(A, /obj/item/stack)) - var/obj/item/stack/S - stack_loop: - for(var/B in holder_contents) - if(ispath(B, A)) - while(amt > 0) - S = locate(B) in holder.loc - if(S.amount >= amt) - S.use(amt) - break stack_loop - else - amt -= S.amount - qdel(S) - else if(ispath(A, /obj/item)) - var/obj/item/I - item_loop: - for(var/B in holder_contents) - if(ispath(B, A)) - while(amt > 0) - I = locate(B) in holder.loc - Deletion.Add(I) - amt-- - break item_loop - else - var/datum/reagent/RG = new A - reagent_loop: - for(var/B in holder_contents) - if(ispath(B, /obj/item/weapon/reagent_containers)) - var/obj/item/RC = locate(B) in holder.loc - if(RC.reagents.has_reagent(RG.id, amt)) - RC.reagents.remove_reagent(RG.id, amt) - RG.volume = amt - Deletion.Add(RG) - break reagent_loop - else if(RC.reagents.has_reagent(RG.id)) - Deletion.Add(RG) - RG.volume += RC.reagents.get_reagent_amount(RG.id) - amt -= RC.reagents.get_reagent_amount(RG.id) - RC.reagents.del_reagent(RG.id) - - for(var/A in R.parts) - for(var/B in Deletion) - if(!istype(B, A)) - Deletion.Remove(B) - qdel(B) - return Deletion - -/datum/crafting_holder/proc/interact(mob/user) - var/list/holder_contents = check_holder() - if(!holder_contents.len) - return - var/dat = "

Construction menu

" - dat += "
" - if(busy) - dat += "Construction inprogress...
" - else - for(var/A in recipes) - var/datum/crafting_recipe/R = recipes[A] - if(check_contents(R, holder_contents)) - dat += "[R.name]
" - dat += "" - - var/datum/browser/popup = new(user, "craft", "Craft", 300, 300) - popup.set_content(dat) - popup.open() - return - -/datum/crafting_holder/Topic(href, href_list) - if(usr.stat || !holder.Adjacent(usr) || usr.lying) - return - if(href_list["make"]) - if(busy) - return - busy = 1 - interact(usr) - var/datum/crafting_recipe/TR = locate(href_list["make"]) - if(construct_item(usr, TR)) - usr << "[TR.name] constructed." - else - usr << "Construction failed." - busy = 0 - interact(usr) diff --git a/code/datums/crafting/recipes.dm b/code/datums/crafting/recipes.dm deleted file mode 100644 index 6dda4d79622..00000000000 --- a/code/datums/crafting/recipes.dm +++ /dev/null @@ -1,137 +0,0 @@ -//Basic crafting components -- Using cheap easily found items to create components that can be used to make more complex objects - -/datum/crafting_recipe/table/igniter - name = "Igniter" - result_path = /obj/item/device/assembly/igniter - reqs = list(/obj/item/weapon/lighter = 1, - /obj/item/stack/cable_coil = 1) - time = 20 - -/datum/crafting_recipe/table/voice - name = "Voice analyzer" - result_path = /obj/item/device/assembly/voice - reqs = list(/obj/item/device/taperecorder = 1, - /obj/item/stack/cable_coil = 1) - time = 20 - -/datum/crafting_recipe/table/infra - name = "Infrared Emitter" - result_path = /obj/item/device/assembly/infra - reqs = list(/obj/item/device/laser_pointer = 1, - /obj/item/stack/cable_coil = 1) - time = 20 - -//Medium crafting - -/datum/crafting_recipe/table/IED - name = "IED" - result_path = /obj/item/weapon/grenade/iedcasing - reqs = list(/obj/item/stack/cable_coil = 1, - /obj/item/device/assembly/igniter = 1, - /obj/item/weapon/reagent_containers/food/drinks/cans = 1, - /datum/reagent/fuel = 10) - time = 80 - -/datum/crafting_recipe/table/stunprod - name = "Stunprod" - result_path = /obj/item/weapon/melee/baton/cattleprod - reqs = list(/obj/item/weapon/handcuffs/cable = 1, - /obj/item/stack/rods = 1, - /obj/item/weapon/wirecutters = 1, - /obj/item/weapon/cell = 1) - time = 80 - parts = list(/obj/item/weapon/cell = 1) - -/datum/crafting_recipe/table/flamethrower - name = "Flamethrower" - result_path = /obj/item/weapon/flamethrower - reqs = list(/obj/item/weapon/weldingtool = 1, - /obj/item/device/assembly/igniter = 1, - /obj/item/stack/rods = 2) - tools = list(/obj/item/weapon/screwdriver) - time = 20 - -/datum/crafting_recipe/table/meteorshot - name = "Meteorshot Shell" - result_path = /obj/item/ammo_casing/shotgun/meteorshot - reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1, - /obj/item/weapon/rcd_ammo = 1, - /obj/item/weapon/stock_parts/manipulator = 2) - tools = list(/obj/item/weapon/screwdriver) - time = 5 - -/datum/crafting_recipe/table/pulseslug - name = "Pulse Slug Shell" - result_path = /obj/item/ammo_casing/shotgun/pulseslug - reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1, - /obj/item/weapon/stock_parts/capacitor/adv = 2, - /obj/item/weapon/stock_parts/micro_laser/ultra = 1) - tools = list(/obj/item/weapon/screwdriver) - time = 5 - -/datum/crafting_recipe/table/dragonsbreath - name = "Dragonsbreath Shell" - result_path = /obj/item/ammo_casing/shotgun/incendiary/dragonsbreath - reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1, - /datum/reagent/phosphorus = 5,) - tools = list(/obj/item/weapon/screwdriver) - time = 5 - -//Advanced crafting - -/datum/crafting_recipe/table/ed209 - name = "ED209" - result_path = /obj/machinery/bot/ed209 - reqs = list(/obj/item/robot_parts/robot_suit = 1, - /obj/item/clothing/head/helmet = 1, - /obj/item/clothing/suit/armor/vest = 1, - /obj/item/robot_parts/l_leg = 1, - /obj/item/robot_parts/r_leg = 1, - /obj/item/stack/sheet/metal = 5, - /obj/item/stack/cable_coil = 5, - /obj/item/weapon/gun/energy/advtaser = 1, - /obj/item/weapon/cell = 1, - /obj/item/device/assembly/prox_sensor = 1, - /obj/item/robot_parts/r_arm = 1) - tools = list(/obj/item/weapon/weldingtool, /obj/item/weapon/screwdriver) - time = 120 - -/datum/crafting_recipe/table/secbot - name = "Secbot" - result_path = /obj/machinery/bot/secbot - reqs = list(/obj/item/device/assembly/signaler = 1, - /obj/item/clothing/head/helmet = 1, - /obj/item/weapon/melee/baton = 1, - /obj/item/device/assembly/prox_sensor = 1, - /obj/item/robot_parts/r_arm = 1) - tools = list(/obj/item/weapon/weldingtool) - time = 120 - -/datum/crafting_recipe/table/cleanbot - name = "Cleanbot" - result_path = /obj/machinery/bot/cleanbot - reqs = list(/obj/item/weapon/reagent_containers/glass/bucket = 1, - /obj/item/device/assembly/prox_sensor = 1, - /obj/item/robot_parts/r_arm = 1) - time = 80 - -/datum/crafting_recipe/table/floorbot - name = "Floorbot" - result_path = /obj/machinery/bot/floorbot - reqs = list(/obj/item/weapon/storage/toolbox/mechanical = 1, - /obj/item/stack/tile/plasteel = 1, - /obj/item/device/assembly/prox_sensor = 1, - /obj/item/robot_parts/r_arm = 1) - time = 80 - -/datum/crafting_recipe/table/medbot - name = "Medbot" - result_path = /obj/machinery/bot/medbot - reqs = list(/obj/item/device/healthanalyzer = 1, - /obj/item/weapon/storage/firstaid = 1, - /obj/item/device/assembly/prox_sensor = 1, - /obj/item/robot_parts/r_arm = 1) - time = 80 - - -///////////////////////////////////////////////////////// \ No newline at end of file diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index d202f29d8f9..f3062199ec7 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -441,7 +441,7 @@ client usr << "This can only be used on instances of type /mob" return - var/new_name = copytext(sanitize(input(usr,"What would you like to name this mob?","Input a name",M.real_name) as text|null),1,MAX_NAME_LEN) + var/new_name = sanitize(copytext(input(usr,"What would you like to name this mob?","Input a name",M.real_name) as text|null,1,MAX_NAME_LEN)) if( !new_name || !M ) return message_admins("Admin [key_name_admin(usr)] renamed [key_name_admin(M)] to [new_name].") @@ -627,7 +627,7 @@ client for(var/obj/Obj in world) if(Obj.type == O_type) i++ - del(Obj) + qdel(Obj) if(!i) usr << "No objects of this type exist" return @@ -638,7 +638,7 @@ client for(var/obj/Obj in world) if(istype(Obj,O_type)) i++ - del(Obj) + qdel(Obj) if(!i) usr << "No objects of this type exist" return diff --git a/code/datums/helper_datums/construction_datum.dm b/code/datums/helper_datums/construction_datum.dm index ffede1e6957..0eb4d73dfde 100644 --- a/code/datums/helper_datums/construction_datum.dm +++ b/code/datums/helper_datums/construction_datum.dm @@ -231,7 +231,7 @@ user.visible_message(fixText(state["vis_msg"],user),fixText(state["self_msg"],user)) if("delete" in state) - del(used_atom) + qdel(used_atom) else if("spawn" in state) var/spawntype=state["spawn"] var/atom/A = new spawntype(holder.loc) diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index a4cde9f99e0..70024bf68d6 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -49,7 +49,7 @@ //must succeed in most cases proc/setTeleatom(atom/movable/ateleatom) if(istype(ateleatom, /obj/effect) && !istype(ateleatom, /obj/effect/dummy/chameleon)) - del(ateleatom) + qdel(ateleatom) return 0 if(istype(ateleatom)) teleatom = ateleatom @@ -190,7 +190,7 @@ teleatom.visible_message("\red The [teleatom] bounces off of the portal!") return 0 - if(destination.z == 2) //centcomm z-level + if((destination.z in config.admin_levels)) //centcomm z-level if(istype(teleatom, /obj/mecha)) var/obj/mecha/MM = teleatom MM.occupant << "\red The mech would not survive the jump to a location so far away!" @@ -200,6 +200,6 @@ return 0 - if(destination.z > 7) //Away mission z-levels + if(!(destination.z in config.player_levels)) //Away mission z-levels return 0 return 1 \ No newline at end of file diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 7bcb54660e8..905d47d36b8 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -70,11 +70,6 @@ datum/mind if(!istype(new_character)) world.log << "## DEBUG: transfer_to(): Some idiot has tried to transfer_to() a non mob/living mob. Please inform Carn" if(current) //remove ourself from our old body's mind variable - if(changeling) - current.remove_changeling_powers() - current.verbs -= /datum/changeling/proc/EvolutionMenu - if(vampire) - current.remove_vampire_powers() current.mind = null if(new_character.mind) //remove any mind currently in our new body's mind variable @@ -85,10 +80,6 @@ datum/mind current = new_character //link ourself to our new body new_character.mind = src //and link our new body to ourself - if(changeling) - new_character.make_changeling() - if(vampire) - new_character.make_vampire() if(active) new_character.key = key //now transfer the key to link the client to our new body @@ -455,7 +446,7 @@ datum/mind assigned_role = new_role else if (href_list["memory_edit"]) - var/new_memo = copytext(sanitize(input("Write new memory", "Memory", memory) as null|message),1,MAX_MESSAGE_LEN) + var/new_memo = sanitize(copytext(input("Write new memory", "Memory", memory) as null|message,1,MAX_MESSAGE_LEN)) if (isnull(new_memo)) return memory = new_memo @@ -475,7 +466,7 @@ datum/mind if(!def_value)//If it's a custom objective, it will be an empty string. def_value = "custom" - var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "blood", "debrain", "protect", "prevent", "harm", "speciesist", "brig", "hijack", "escape", "survive", "steal", "download", "nuclear", "capture", "absorb", "destroy", "maroon", "custom") + var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "blood", "debrain", "protect", "prevent", "harm", "speciesist", "brig", "hijack", "escape", "survive", "steal", "download", "nuclear", "capture", "absorb", "destroy", "maroon", "identity theft", "custom") if (!new_obj_type) return var/datum/objective/new_objective = null @@ -588,8 +579,25 @@ datum/mind new_objective.owner = src new_objective.target_amount = target_number + if("identity theft") + var/list/possible_targets = list("Free objective") + for(var/datum/mind/possible_target in ticker.minds) + if ((possible_target != src) && istype(possible_target.current, /mob/living/carbon/human)) + possible_targets += possible_target.current + + var/new_target = input("Select target:", "Objective target") as null|anything in possible_targets + if (!new_target) + return + var/datum/mind/targ = new_target + if(!istype(targ)) + log_debug("Invalid target for identity theft objective, cancelling") + return + new_objective = new /datum/objective/escape/escape_with_identity + new_objective.owner = src + new_objective.target = new_target + new_objective.explanation_text = "Escape on the shuttle or an escape pod with the identity of [targ.current.real_name], the [targ.assigned_role] while wearing their identification card." if ("custom") - var/expl = copytext(sanitize(input("Custom objective:", "Objective", objective ? objective.explanation_text : "") as text|null),1,MAX_MESSAGE_LEN) + var/expl = sanitize(copytext(input("Custom objective:", "Objective", objective ? objective.explanation_text : "") as text|null,1,MAX_MESSAGE_LEN)) if (!expl) return new_objective = new /datum/objective new_objective.owner = src @@ -727,7 +735,7 @@ datum/mind var/obj/item/device/flash/flash = locate() in L if (!flash) usr << "\red Deleting flash failed!" - del(flash) + qdel(flash) if("repairflash") var/list/L = current.get_contents() @@ -740,7 +748,7 @@ datum/mind if("reequip") var/list/L = current.get_contents() var/obj/item/device/flash/flash = locate() in L - del(flash) + qdel(flash) take_uplink() var/fail = 0 fail |= !ticker.mode.equip_traitor(current, 1) @@ -843,7 +851,6 @@ datum/mind ticker.mode.changelings -= src special_role = null current.remove_changeling_powers() - current.verbs -= /datum/changeling/proc/EvolutionMenu if(changeling) del(changeling) current << "You grow weak and lose your powers! You are no longer a changeling and are stuck in your current form!" log_admin("[key_name_admin(usr)] has de-changeling'ed [current].") @@ -920,17 +927,17 @@ datum/mind if("lair") current.loc = get_turf(locate("landmark*Syndicate-Spawn")) if("dressup") - del(H.belt) - del(H.back) - del(H.l_ear) - del(H.r_ear) - del(H.gloves) - del(H.head) - del(H.shoes) - del(H.wear_id) - del(H.wear_pda) - del(H.wear_suit) - del(H.w_uniform) + qdel(H.belt) + qdel(H.back) + qdel(H.l_ear) + qdel(H.r_ear) + qdel(H.gloves) + qdel(H.head) + qdel(H.shoes) + qdel(H.wear_id) + qdel(H.wear_pda) + qdel(H.wear_suit) + qdel(H.w_uniform) if (!ticker.mode.equip_syndicate(current)) usr << "\red Equipping a syndicate failed!" @@ -1075,7 +1082,7 @@ datum/mind switch(href_list["common"]) if("undress") for(var/obj/item/W in current) - current.drop_from_inventory(W) + current.unEquip(W, 1) if("takeuplink") take_uplink() memory = null//Remove any memory they may have had. @@ -1143,7 +1150,7 @@ datum/mind proc/take_uplink() var/obj/item/device/uplink/hidden/H = find_syndicate_uplink() if(H) - del(H) + qdel(H) proc/make_AI_Malf() @@ -1184,17 +1191,17 @@ datum/mind current.loc = get_turf(locate("landmark*Syndicate-Spawn")) var/mob/living/carbon/human/H = current - del(H.belt) - del(H.back) - del(H.l_ear) - del(H.r_ear) - del(H.gloves) - del(H.head) - del(H.shoes) - del(H.wear_id) - del(H.wear_pda) - del(H.wear_suit) - del(H.w_uniform) + qdel(H.belt) + qdel(H.back) + qdel(H.l_ear) + qdel(H.r_ear) + qdel(H.gloves) + qdel(H.head) + qdel(H.shoes) + qdel(H.wear_id) + qdel(H.wear_pda) + qdel(H.wear_suit) + qdel(H.w_uniform) ticker.mode.equip_syndicate(current) @@ -1283,7 +1290,7 @@ datum/mind var/list/L = current.get_contents() var/obj/item/device/flash/flash = locate() in L - del(flash) + qdel(flash) take_uplink() var/fail = 0 // fail |= !ticker.mode.equip_traitor(current, 1) diff --git a/code/datums/periodic_news.dm b/code/datums/periodic_news.dm index 976ef536cb4..ffa52bffdc6 100644 --- a/code/datums/periodic_news.dm +++ b/code/datums/periodic_news.dm @@ -8,6 +8,7 @@ author = "Nanotrasen Editor" channel_name = "Tau Ceti Daily" can_be_redacted = 0 + message_type = "Story" revolution_inciting_event @@ -129,12 +130,6 @@ proc/check_for_newscaster_updates(type) proc/announce_newscaster_news(datum/news_announcement/news) - var/datum/feed_message/newMsg = new /datum/feed_message - newMsg.author = news.author - newMsg.is_admin_message = !news.can_be_redacted - - newMsg.body = news.message - var/datum/feed_channel/sendto for(var/datum/feed_channel/FC in news_network.network_channels) if(FC.channel_name == news.channel_name) @@ -148,6 +143,12 @@ proc/announce_newscaster_news(datum/news_announcement/news) sendto.locked = 1 sendto.is_admin_channel = 1 news_network.network_channels += sendto + + var/datum/feed_message/newMsg = new /datum/feed_message + newMsg.author = news.author ? news.author : sendto.author + newMsg.is_admin_message = !news.can_be_redacted + newMsg.body = news.message + newMsg.message_type = news.message_type sendto.messages += newMsg diff --git a/code/datums/recipe.dm b/code/datums/recipe.dm index d2c747dd5b8..4f2750c0c06 100644 --- a/code/datums/recipe.dm +++ b/code/datums/recipe.dm @@ -79,7 +79,7 @@ var/obj/result_obj = new result(container) for (var/obj/O in (container.contents-result_obj)) O.reagents.trans_to(result_obj, O.reagents.total_volume) - del(O) + qdel(O) container.reagents.clear_reagents() return result_obj @@ -91,7 +91,7 @@ O.reagents.del_reagent("nutriment") O.reagents.update_total() O.reagents.trans_to(result_obj, O.reagents.total_volume) - del(O) + qdel(O) container.reagents.clear_reagents() return result_obj diff --git a/code/datums/spell.dm b/code/datums/spell.dm index d6c2350510d..e03f172f2a2 100644 --- a/code/datums/spell.dm +++ b/code/datums/spell.dm @@ -48,7 +48,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin var/icon_power_button var/power_button_name -/obj/effect/proc_holder/spell/wizard/proc/cast_check(skipcharge = 0, mob/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell +/obj/effect/proc_holder/spell/wizard/proc/cast_check(skipcharge = 0, mob/living/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell if(!(src in user.spell_list)) user << "You shouldn't have this spell! Something's wrong." @@ -60,7 +60,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin caster.reset_view(0) return 0 - if(user.z == 2 && !centcom_cancast) //Certain spells are not allowed on the centcom zlevel + if((user.z in config.admin_levels) && !centcom_cancast) //Certain spells are not allowed on the centcom zlevel return 0 if(!skipcharge) @@ -75,27 +75,27 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin return 0 if(!ghost) - if(usr.stat && !stat_allowed) - usr << "Not when you're incapacitated." + if(user.stat && !stat_allowed) + user << "Not when you're incapacitated." return 0 - if(ishuman(usr) || ismonkey(usr)) - if(istype(usr.wear_mask, /obj/item/clothing/mask/muzzle)) - usr << "Mmmf mrrfff!" + if(ishuman(user) || ismonkey(user)) + if(user.is_muzzled()) + user << "Mmmf mrrfff!" return 0 var/obj/effect/proc_holder/spell/wizard/noclothes/spell = locate() in user.spell_list if(clothes_req && !(spell && istype(spell)))//clothes check - if(!istype(usr, /mob/living/carbon/human)) - usr << "You aren't a human, Why are you trying to cast a human spell, silly non-human? Casting human spells is for humans." + if(!istype(user, /mob/living/carbon/human)) + user << "You aren't a human, Why are you trying to cast a human spell, silly non-human? Casting human spells is for humans." return 0 - if(!istype(usr:wear_suit, /obj/item/clothing/suit/wizrobe) && !istype(user:wear_suit, /obj/item/clothing/suit/space/rig/wizard)) - usr << "I don't feel strong enough without my robe." + if(!istype(user:wear_suit, /obj/item/clothing/suit/wizrobe) && !istype(user:wear_suit, /obj/item/clothing/suit/space/rig/wizard)) + user << "I don't feel strong enough without my robe." return 0 - if(!istype(usr:shoes, /obj/item/clothing/shoes/sandal)) - usr << "I don't feel strong enough without my sandals." + if(!istype(user:shoes, /obj/item/clothing/shoes/sandal)) + user << "I don't feel strong enough without my sandals." return 0 - if(!istype(usr:head, /obj/item/clothing/head/wizard) && !istype(usr:head, /obj/item/clothing/head/helmet/space/rig/wizard)) - usr << "I don't feel strong enough without my hat." + if(!istype(user:head, /obj/item/clothing/head/wizard) && !istype(user:head, /obj/item/clothing/head/helmet/space/rig/wizard)) + user << "I don't feel strong enough without my hat." return 0 if(!skipcharge) diff --git a/code/datums/spells/charge.dm b/code/datums/spells/charge.dm index b4603f5e6b1..cabde8c7181 100644 --- a/code/datums/spells/charge.dm +++ b/code/datums/spells/charge.dm @@ -53,8 +53,8 @@ W.icon_state = initial(W.icon_state) charged_item = I break - else if(istype(item, /obj/item/weapon/cell/)) - var/obj/item/weapon/cell/C = item + else if(istype(item, /obj/item/weapon/stock_parts/cell/)) + var/obj/item/weapon/stock_parts/cell/C = item if(prob(80)) C.maxcharge -= 200 if(C.maxcharge <= 1) //Div by 0 protection @@ -66,8 +66,8 @@ else if(item.contents) var/obj/I = null for(I in item.contents) - if(istype(I, /obj/item/weapon/cell/)) - var/obj/item/weapon/cell/C = I + if(istype(I, /obj/item/weapon/stock_parts/cell/)) + var/obj/item/weapon/stock_parts/cell/C = I if(prob(80)) C.maxcharge -= 200 if(C.maxcharge <= 1) //Div by 0 protection diff --git a/code/datums/spells/genetic.dm b/code/datums/spells/genetic.dm index 45be50f0b75..f9d327a5723 100644 --- a/code/datums/spells/genetic.dm +++ b/code/datums/spells/genetic.dm @@ -20,8 +20,8 @@ for(var/mob/living/target in targets) for(var/x in mutations) target.mutations.Add(x) - if(x == M_HULK && ishuman(target)) - target:hulk_time=world.time + duration + /* if(x == HULK && ishuman(target)) + target:hulk_time=world.time + duration */ target.disabilities |= disabilities target.update_mutations() //update target's mutation overlays spawn(duration) diff --git a/code/datums/spells/horsemask.dm b/code/datums/spells/horsemask.dm index b04969d2d98..5f45dc41aaa 100644 --- a/code/datums/spells/horsemask.dm +++ b/code/datums/spells/horsemask.dm @@ -26,7 +26,7 @@ if(!target) return - if(target.type in compatible_mobs || ishuman(target)) + if((target.type in compatible_mobs) || ishuman(target)) user << "It'd be stupid to curse [target] with a horse's head!" return @@ -35,12 +35,13 @@ return var/obj/item/clothing/mask/horsehead/magichead = new /obj/item/clothing/mask/horsehead - magichead.canremove = 0 //curses! + magichead.flags |= NODROP //curses! magichead.flags_inv = null //so you can still see their face magichead.voicechange = 1 //NEEEEIIGHH 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.drop_from_inventory(target.wear_mask) + if(!target.unEquip(target.wear_mask)) + del target.wear_mask target.equip_to_slot_if_possible(magichead, slot_wear_mask, 1, 1) flick("e_flash", target.flash) diff --git a/code/datums/spells/summonitem.dm b/code/datums/spells/summonitem.dm index cca82c3c0c0..05b835605d4 100644 --- a/code/datums/spells/summonitem.dm +++ b/code/datums/spells/summonitem.dm @@ -59,7 +59,7 @@ item_to_retrive = null break - M.u_equip(item_to_retrive) + M.unEquip(item_to_retrive) if(ishuman(M)) //Edge case housekeeping var/mob/living/carbon/human/C = M diff --git a/code/datums/spells/wizard.dm b/code/datums/spells/wizard.dm index 5672052e0a2..ae507556181 100644 --- a/code/datums/spells/wizard.dm +++ b/code/datums/spells/wizard.dm @@ -48,7 +48,7 @@ include_user = 1 centcom_cancast = 0 - mutations = list(M_LASER, M_HULK) + mutations = list(LASER, HULK) duration = 300 cooldown_min = 300 //25 deciseconds reduction per rank diff --git a/code/datums/sun.dm b/code/datums/sun.dm index 1379a7b9d87..eafbcd1ee0c 100644 --- a/code/datums/sun.dm +++ b/code/datums/sun.dm @@ -1,5 +1,7 @@ #define SOLAR_UPDATE_TIME 600 //duration between two updates of the whole sun/solars positions +var/global/datum/sun/sun + /datum/sun var/angle var/dx @@ -17,10 +19,11 @@ solar_next_update = world.time // init the timer angle = rand (0,360) // the station position to the sun is randomised at round start +/* HANDLED IN PROCESS SCHEDULER /hook/startup/proc/createSun() sun = new /datum/sun() return 1 - +*/ // calculate the sun's position given the time of day // at the standard rate (100%) the angle is increase/decreased by 6 degrees every minute. // a full rotation thus take a game hour in that case @@ -50,54 +53,9 @@ dx = s/abs(s) dy = c / abs(s) - - for(var/obj/machinery/power/M in solars_list) - - if(!M.powernet) - solars_list.Remove(M) + //now tell the solar control computers to update their status and linked devices + for(var/obj/machinery/power/solar_control/SC in solars_list) + if(!SC.powernet) + solars_list.Remove(SC) continue - - // Solar Tracker - if(istype(M, /obj/machinery/power/tracker)) - var/obj/machinery/power/tracker/T = M - T.set_angle(angle) - - // Solar Control - else if(istype(M, /obj/machinery/power/solar_control)) - var/obj/machinery/power/solar_control/C = M - if(C.track == 1) //if manual tracking... - C.tracker_update() //...update the position (not passing an angle, it is handled internally for manual tracking) - - // Solar Panel - else if(istype(M, /obj/machinery/power/solar)) - var/obj/machinery/power/solar/S = M - if(S.control) - occlusion(S) - - -// for a solar panel, trace towards sun to see if we're in shadow -/datum/sun/proc/occlusion(var/obj/machinery/power/solar/S) - - var/ax = S.x // start at the solar panel - var/ay = S.y - var/turf/T = null - - for(var/i = 1 to 20) // 20 steps is enough - ax += dx // do step - ay += dy - - T = locate( round(ax,0.5),round(ay,0.5),S.z) - - if(T.x == 1 || T.x==world.maxx || T.y==1 || T.y==world.maxy) // not obscured if we reach the edge - break - - if(T.density) // if we hit a solid turf, panel is obscured - S.obscured = 1 - return - - S.obscured = 0 // if hit the edge or stepped 20 times, not obscured - S.update_solar_exposure() - - - - + SC.update() diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm old mode 100755 new mode 100644 index de49b586def..8497680bd2d --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -1,1204 +1,1297 @@ -//SUPPLY PACKS -//NOTE: only secure crate types use the access var (and are lockable) -//NOTE: hidden packs only show up when the computer has been hacked. -//ANOTER NOTE: Contraband is obtainable through modified supplycomp circuitboards. -//BIG NOTE: Don't add living things to crates, that's bad, it will break the shuttle. -//NEW NOTE: Do NOT set the price of any crates below 7 points. Doing so allows infinite points. - -var/list/all_supply_groups = list("Operations","Security","Hospitality","Engineering","Medical / Science","Hydroponics","Organic") - -/datum/supply_packs - var/name = null - var/list/contains = list() - var/manifest = "" - var/amount = null - var/cost = null - var/containertype = null - var/containername = null - var/access = null - var/hidden = 0 - var/contraband = 0 - var/group = "Operations" - -/datum/supply_packs/New() - manifest += "
    " - for(var/path in contains) - if(!path) continue - var/atom/movable/AM = new path() - manifest += "
  • [AM.name]
  • " - AM.loc = null //just to make sure they're deleted by the garbage collector - manifest += "
" - -/datum/supply_packs/specialops - name = "Special Ops supplies" - contains = list(/obj/item/weapon/storage/box/emps, - /obj/item/weapon/grenade/smokebomb, - /obj/item/weapon/grenade/smokebomb, - /obj/item/weapon/grenade/smokebomb, - /obj/item/weapon/pen/paralysis, - /obj/item/weapon/grenade/chem_grenade/incendiary) - cost = 20 - containertype = /obj/structure/closet/crate - containername = "Special Ops crate" - group = "Security" - hidden = 1 - -/datum/supply_packs/syndicate - name = "ERROR_NULL_ENTRY" - contains = list(/obj/item/weapon/storage/box/syndicate) - cost = 140 - containertype = /obj/structure/closet/crate - containername = "crate" - hidden = 1 - -/datum/supply_packs/food - name = "Food crate" - contains = list(/obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/drinks/milk, - /obj/item/weapon/reagent_containers/food/drinks/milk, - /obj/item/weapon/storage/fancy/egg_box, - /obj/item/weapon/reagent_containers/food/snacks/grown/banana, - /obj/item/weapon/reagent_containers/food/snacks/grown/banana) - cost = 10 - containertype = /obj/structure/closet/crate/freezer - containername = "Food crate" - group = "Hospitality" - -/datum/supply_packs/monkey - name = "Monkey crate" - contains = list (/obj/item/weapon/storage/box/monkeycubes) - cost = 20 - containertype = /obj/structure/closet/crate/freezer - containername = "Monkey crate" - group = "Hydroponics" - -/datum/supply_packs/farwa - name = "Farwa crate" - contains = list (/obj/item/weapon/storage/box/farwacubes) - cost = 30 - containertype = /obj/structure/closet/crate/freezer - containername = "Farwa crate" - group = "Hydroponics" - -/datum/supply_packs/skrell - name = "Neaera crate" - contains = list (/obj/item/weapon/storage/box/neaeracubes) - cost = 30 - containertype = /obj/structure/closet/crate/freezer - containername = "Neaera crate" - group = "Hydroponics" - -/datum/supply_packs/stok - name = "Stok crate" - contains = list (/obj/item/weapon/storage/box/stokcubes) - cost = 30 - containertype = /obj/structure/closet/crate/freezer - containername = "Stok crate" - group = "Hydroponics" - -/datum/supply_packs/beanbagammo - name = "Beanbag shells" - contains = list(/obj/item/ammo_casing/shotgun/beanbag, - /obj/item/ammo_casing/shotgun/beanbag, - /obj/item/ammo_casing/shotgun/beanbag, - /obj/item/ammo_casing/shotgun/beanbag, - /obj/item/ammo_casing/shotgun/beanbag, - /obj/item/ammo_casing/shotgun/beanbag, - /obj/item/ammo_casing/shotgun/beanbag, - /obj/item/ammo_casing/shotgun/beanbag, - /obj/item/ammo_casing/shotgun/beanbag, - /obj/item/ammo_casing/shotgun/beanbag) - cost = 10 - containertype = /obj/structure/closet/crate - containername = "Beanbag shells" - group = "Security" - -/datum/supply_packs/toner - name = "Toner Cartridges" - contains = list(/obj/item/device/toner, - /obj/item/device/toner, - /obj/item/device/toner, - /obj/item/device/toner, - /obj/item/device/toner, - /obj/item/device/toner) - cost = 10 - containertype = /obj/structure/closet/crate - containername = "Toner Cartridges" - group = "Operations" - -/datum/supply_packs/party - name = "Party equipment" - contains = list(/obj/item/weapon/storage/box/drinkingglasses, - /obj/item/weapon/reagent_containers/food/drinks/shaker, - /obj/item/weapon/reagent_containers/food/drinks/bottle/patron, - /obj/item/weapon/reagent_containers/food/drinks/bottle/goldschlager, - /obj/item/weapon/storage/fancy/cigarettes/dromedaryco, - /obj/item/weapon/lipstick/random, - /obj/item/weapon/reagent_containers/food/drinks/cans/ale, - /obj/item/weapon/reagent_containers/food/drinks/cans/ale, - /obj/item/weapon/reagent_containers/food/drinks/cans/beer, - /obj/item/weapon/reagent_containers/food/drinks/cans/beer, - /obj/item/weapon/reagent_containers/food/drinks/cans/beer, - /obj/item/weapon/reagent_containers/food/drinks/cans/beer) - cost = 20 - containertype = /obj/structure/closet/crate - containername = "Party equipment" - group = "Hospitality" - -/datum/supply_packs/internals - name = "Internals crate" - contains = list(/obj/item/clothing/mask/gas, - /obj/item/clothing/mask/gas, - /obj/item/clothing/mask/gas, - /obj/item/weapon/tank/air, - /obj/item/weapon/tank/air, - /obj/item/weapon/tank/air) - cost = 10 - containertype = /obj/structure/closet/crate/internals - containername = "Internals crate" - group = "Engineering" - -/datum/supply_packs/evacuation - name = "Emergency equipment" - contains = list(/obj/item/weapon/storage/toolbox/emergency, - /obj/item/weapon/storage/toolbox/emergency, - /obj/item/clothing/suit/storage/hazardvest, - /obj/item/clothing/suit/storage/hazardvest, - /obj/item/weapon/tank/emergency_oxygen, - /obj/item/weapon/tank/emergency_oxygen, - /obj/item/weapon/tank/emergency_oxygen, - /obj/item/weapon/tank/emergency_oxygen, - /obj/item/weapon/tank/emergency_oxygen, - /obj/item/clothing/mask/gas, - /obj/item/clothing/mask/gas, - /obj/item/clothing/mask/gas, - /obj/item/clothing/mask/gas, - /obj/item/clothing/mask/gas) - cost = 35 - containertype = /obj/structure/closet/crate/internals - 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, - /obj/item/weapon/reagent_containers/glass/bucket, - /obj/item/weapon/reagent_containers/glass/bucket, - /obj/item/weapon/mop, - /obj/item/weapon/caution, - /obj/item/weapon/caution, - /obj/item/weapon/caution, - /obj/item/weapon/storage/bag/trash, - /obj/item/weapon/reagent_containers/spray/cleaner, - /obj/item/weapon/reagent_containers/glass/rag, - /obj/item/weapon/grenade/chem_grenade/cleaner, - /obj/item/weapon/grenade/chem_grenade/cleaner, - /obj/item/weapon/grenade/chem_grenade/cleaner) - cost = 10 - containertype = /obj/structure/closet/crate - containername = "Janitorial supplies" - group = "Operations" - -/datum/supply_packs/janicart - name = "Janitorial Cart and Galoshes crate" - contains = list(/obj/structure/janitorialcart, - /obj/item/clothing/shoes/galoshes) - cost = 10 - containertype = /obj/structure/largecrate - containername = "janitorial cart crate" - -/datum/supply_packs/lightbulbs - name = "Replacement lights" - contains = list(/obj/item/weapon/storage/box/lights/mixed, - /obj/item/weapon/storage/box/lights/mixed, - /obj/item/weapon/storage/box/lights/mixed) - cost = 10 - containertype = /obj/structure/closet/crate - containername = "Replacement lights" - group = "Engineering" - -/datum/supply_packs/costume - name = "Standard Costume crate" - contains = list(/obj/item/weapon/storage/backpack/clown, - /obj/item/clothing/shoes/clown_shoes, - /obj/item/clothing/mask/gas/clown_hat, - /obj/item/clothing/under/rank/clown, - /obj/item/weapon/bikehorn, - /obj/item/clothing/under/mime, - /obj/item/clothing/shoes/black, - /obj/item/clothing/gloves/color/white, - /obj/item/clothing/mask/gas/mime, - /obj/item/clothing/head/beret, - /obj/item/clothing/suit/suspenders, - /obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing) - cost = 10 - containertype = /obj/structure/closet/crate/secure - containername = "Standard Costumes" - access = access_theatre - group = "Operations" - -/datum/supply_packs/wizard - name = "Wizard costume" - contains = list(/obj/item/weapon/staff, - /obj/item/clothing/suit/wizrobe/fake, - /obj/item/clothing/shoes/sandal, - /obj/item/clothing/head/wizard/fake) - cost = 20 - containertype = /obj/structure/closet/crate - containername = "Wizard costume crate" - group = "Operations" - -/datum/supply_packs/mule - name = "MULEbot Crate" - contains = list(/obj/machinery/bot/mulebot) - cost = 20 - containertype = /obj/structure/largecrate/mule - containername = "MULEbot Crate" - group = "Operations" - -/datum/supply_packs/cargotrain - name = "Cargo Train Tug" - contains = list(/obj/vehicle/train/cargo/engine) - cost = 45 - containertype = /obj/structure/largecrate - containername = "Cargo Train Tug Crate" - group = "Operations" - -/datum/supply_packs/cargotrailer - name = "Cargo Train Trolley" - contains = list(/obj/vehicle/train/cargo/trolley) - cost = 15 - containertype = /obj/structure/largecrate - containername = "Cargo Train Trolley Crate" - group = "Operations" - -/datum/supply_packs/hydroponics // -- Skie - name = "Hydroponics Supply Crate" - contains = list(/obj/item/weapon/reagent_containers/spray/plantbgone, - /obj/item/weapon/reagent_containers/spray/plantbgone, - /obj/item/weapon/reagent_containers/glass/bottle/ammonia, - /obj/item/weapon/reagent_containers/glass/bottle/ammonia, - /obj/item/weapon/hatchet, - /obj/item/weapon/minihoe, - /obj/item/device/analyzer/plant_analyzer, - /obj/item/clothing/gloves/botanic_leather, - /obj/item/clothing/suit/apron, - /obj/item/weapon/minihoe, - /obj/item/weapon/storage/box/botanydisk - ) // Updated with new things - cost = 15 - containertype = /obj/structure/closet/crate/hydroponics - containername = "Hydroponics crate" - access = access_hydroponics - group = "Hydroponics" - -//////// livestock -/datum/supply_packs/organic/cow - name = "Cow Crate" - cost = 30 - containertype = /obj/structure/largecrate/cow - containername = "cow crate" - group = "Organic" - -/datum/supply_packs/organic/goat - name = "Goat Crate" - cost = 25 - containertype = /obj/structure/largecrate/goat - containername = "goat crate" - group = "Organic" - -/datum/supply_packs/organic/chicken - name = "Chicken Crate" - cost = 20 - containertype = /obj/structure/largecrate/chick - containername = "chicken crate" - group = "Organic" - -/datum/supply_packs/organic/corgi - name = "Corgi Crate" - cost = 50 - containertype = /obj/structure/largecrate/lisa - containername = "corgi crate" - group = "Organic" - -/datum/supply_packs/organic/cat - name = "Cat crate" - cost = 50 //Cats are worth as much as corgis. - containertype = /obj/structure/largecrate/cat - containername = "cat crate" - group = "Organic" - -/datum/supply_packs/organic/fox - name = "Fox Crate" - cost = 55 //Foxes are cool. - containertype = /obj/structure/closet/critter/fox - containername = "fox crate" - group = "Organic" - -/datum/supply_packs/seeds - name = "Seeds Crate" - contains = list(/obj/item/seeds/chiliseed, - /obj/item/seeds/berryseed, - /obj/item/seeds/cornseed, - /obj/item/seeds/eggplantseed, - /obj/item/seeds/tomatoseed, - /obj/item/seeds/soyaseed, - /obj/item/seeds/wheatseed, - /obj/item/seeds/carrotseed, - /obj/item/seeds/sunflowerseed, - /obj/item/seeds/chantermycelium, - /obj/item/seeds/potatoseed, - /obj/item/seeds/sugarcaneseed) - cost = 10 - containertype = /obj/structure/closet/crate/hydroponics - containername = "Seeds crate" - access = access_hydroponics - group = "Hydroponics" - -/datum/supply_packs/weedcontrol - name = "Weed Control Crate" - contains = list(/obj/item/weapon/scythe, - /obj/item/clothing/mask/gas, - /obj/item/weapon/grenade/chem_grenade/antiweed, - /obj/item/weapon/grenade/chem_grenade/antiweed) - cost = 20 - containertype = /obj/structure/closet/crate/secure/hydrosec - containername = "Weed control crate" - access = access_hydroponics - group = "Hydroponics" - -/datum/supply_packs/exoticseeds - name = "Exotic Seeds Crate" - contains = list(/obj/item/seeds/nettleseed, - /obj/item/seeds/replicapod, - /obj/item/seeds/replicapod, - /obj/item/seeds/replicapod, - /obj/item/seeds/plumpmycelium, - /obj/item/seeds/libertymycelium, - /obj/item/seeds/amanitamycelium, - /obj/item/seeds/reishimycelium, - /obj/item/seeds/bananaseed, - /obj/item/seeds/eggyseed, - /obj/item/seeds/bloodtomatoseed) - cost = 15 - containertype = /obj/structure/closet/crate/hydroponics - containername = "Exotic Seeds crate" - access = access_hydroponics - group = "Hydroponics" - -/datum/supply_packs/medical - name = "Medical crate" - contains = list(/obj/item/weapon/storage/firstaid/regular, - /obj/item/weapon/storage/firstaid/fire, - /obj/item/weapon/storage/firstaid/toxin, - /obj/item/weapon/storage/firstaid/o2, - /obj/item/weapon/storage/firstaid/adv, - /obj/item/weapon/reagent_containers/glass/bottle/antitoxin, - /obj/item/weapon/reagent_containers/glass/bottle/inaprovaline, - /obj/item/weapon/reagent_containers/glass/bottle/stoxin, - /obj/item/weapon/storage/box/syringes, - /obj/item/weapon/storage/box/autoinjectors) - cost = 10 - containertype = /obj/structure/closet/crate/medical - containername = "Medical crate" - group = "Medical / Science" - -/datum/supply_packs/virus - name = "Virus crate" -/* contains = list(/obj/item/weapon/reagent_containers/glass/bottle/flu_virion, - /obj/item/weapon/reagent_containers/glass/bottle/cold, - /obj/item/weapon/reagent_containers/glass/bottle/epiglottis_virion, - /obj/item/weapon/reagent_containers/glass/bottle/liver_enhance_virion, - /obj/item/weapon/reagent_containers/glass/bottle/fake_gbs, - /obj/item/weapon/reagent_containers/glass/bottle/magnitis, - /obj/item/weapon/reagent_containers/glass/bottle/pierrot_throat, - /obj/item/weapon/reagent_containers/glass/bottle/brainrot, - /obj/item/weapon/reagent_containers/glass/bottle/hullucigen_virion, - /obj/item/weapon/storage/box/syringes, - /obj/item/weapon/storage/box/beakers, - /obj/item/weapon/reagent_containers/glass/bottle/mutagen)*/ - contains = list(/obj/item/weapon/virusdish/random, - /obj/item/weapon/virusdish/random, - /obj/item/weapon/virusdish/random, - /obj/item/weapon/virusdish/random) - cost = 25 - containertype = "/obj/structure/closet/crate/secure" - containername = "Virus crate" - access = access_cmo - group = "Medical / Science" - -/datum/supply_packs/metal50 - name = "50 Metal Sheets" - contains = list(/obj/item/stack/sheet/metal) - amount = 50 - cost = 10 - containertype = /obj/structure/closet/crate - containername = "Metal sheets crate" - group = "Engineering" - -/datum/supply_packs/glass50 - name = "50 Glass Sheets" - contains = list(/obj/item/stack/sheet/glass) - amount = 50 - cost = 10 - containertype = /obj/structure/closet/crate - containername = "Glass sheets crate" - group = "Engineering" - -/datum/supply_packs/electrical - name = "Electrical maintenance crate" - contains = list(/obj/item/weapon/storage/toolbox/electrical, - /obj/item/weapon/storage/toolbox/electrical, - /obj/item/clothing/gloves/yellow, - /obj/item/clothing/gloves/yellow, - /obj/item/weapon/cell, - /obj/item/weapon/cell, - /obj/item/weapon/cell/high, - /obj/item/weapon/cell/high) - cost = 15 - containertype = /obj/structure/closet/crate - containername = "Electrical maintenance crate" - group = "Engineering" - -/datum/supply_packs/mechanical - name = "Mechanical maintenance crate" - contains = list(/obj/item/weapon/storage/belt/utility/full, - /obj/item/weapon/storage/belt/utility/full, - /obj/item/weapon/storage/belt/utility/full, - /obj/item/clothing/suit/storage/hazardvest, - /obj/item/clothing/suit/storage/hazardvest, - /obj/item/clothing/suit/storage/hazardvest, - /obj/item/clothing/head/welding, - /obj/item/clothing/head/welding, - /obj/item/clothing/head/hardhat) - cost = 10 - containertype = /obj/structure/closet/crate - containername = "Mechanical maintenance crate" - group = "Engineering" - -/datum/supply_packs/watertank - name = "Water tank crate" - contains = list(/obj/structure/reagent_dispensers/watertank) - cost = 8 - containertype = /obj/structure/largecrate - containername = "water tank crate" - group = "Hydroponics" - -/datum/supply_packs/fueltank - name = "Fuel tank crate" - contains = list(/obj/structure/reagent_dispensers/fueltank) - cost = 8 - containertype = /obj/structure/largecrate - containername = "fuel tank crate" - group = "Engineering" - -/datum/supply_packs/coolanttank - name = "Coolant tank crate" - contains = list(/obj/structure/reagent_dispensers/coolanttank) - cost = 16 - containertype = /obj/structure/largecrate - containername = "coolant tank crate" - group = "Medical / Science" - - -/datum/supply_packs/solar - name = "Solar Pack crate" - contains = list(/obj/item/solar_assembly, - /obj/item/solar_assembly, - /obj/item/solar_assembly, - /obj/item/solar_assembly, - /obj/item/solar_assembly, - /obj/item/solar_assembly, - /obj/item/solar_assembly, - /obj/item/solar_assembly, - /obj/item/solar_assembly, - /obj/item/solar_assembly, - /obj/item/solar_assembly, - /obj/item/solar_assembly, - /obj/item/solar_assembly, - /obj/item/solar_assembly, - /obj/item/solar_assembly, - /obj/item/solar_assembly, - /obj/item/solar_assembly, - /obj/item/solar_assembly, - /obj/item/solar_assembly, - /obj/item/solar_assembly, - /obj/item/solar_assembly, // 21 Solar Assemblies. 1 Extra for the controller - /obj/item/weapon/circuitboard/solar_control, - /obj/item/weapon/tracker_electronics, - /obj/item/weapon/paper/solar) - cost = 20 - containertype = /obj/structure/closet/crate - containername = "solar pack crate" - group = "Engineering" - -/datum/supply_packs/engine - name = "Emitter crate" - contains = list(/obj/machinery/power/emitter, - /obj/machinery/power/emitter) - cost = 10 - containertype = /obj/structure/closet/crate/secure - containername = "Emitter crate" - access = access_ce - group = "Engineering" - -/datum/supply_packs/engine/field_gen - name = "Field Generator crate" - contains = list(/obj/machinery/field_generator, - /obj/machinery/field_generator) - containertype = /obj/structure/closet/crate/secure - containername = "Field Generator crate" - access = access_ce - group = "Engineering" - -/datum/supply_packs/engine/sing_gen - name = "Singularity Generator crate" - contains = list(/obj/machinery/the_singularitygen) - containertype = /obj/structure/closet/crate/secure - containername = "Singularity Generator crate" - access = access_ce - group = "Engineering" - -/datum/supply_packs/engine/collector - name = "Collector crate" - contains = list(/obj/machinery/power/rad_collector, - /obj/machinery/power/rad_collector, - /obj/machinery/power/rad_collector) - containername = "Collector crate" - group = "Engineering" - -/datum/supply_packs/engine/PA - name = "Particle Accelerator crate" - cost = 40 - contains = list(/obj/structure/particle_accelerator/fuel_chamber, - /obj/machinery/particle_accelerator/control_box, - /obj/structure/particle_accelerator/particle_emitter/center, - /obj/structure/particle_accelerator/particle_emitter/left, - /obj/structure/particle_accelerator/particle_emitter/right, - /obj/structure/particle_accelerator/power_box, - /obj/structure/particle_accelerator/end_cap) - containertype = /obj/structure/closet/crate/secure - containername = "Particle Accelerator crate" - access = access_ce - group = "Engineering" - -/datum/supply_packs/mecha_ripley - name = "Circuit Crate (\"Ripley\" APLU)" - contains = list(/obj/item/weapon/book/manual/ripley_build_and_repair, - /obj/item/weapon/circuitboard/mecha/ripley/main, //TEMPORARY due to lack of circuitboard printer - /obj/item/weapon/circuitboard/mecha/ripley/peripherals) //TEMPORARY due to lack of circuitboard printer - cost = 30 - containertype = /obj/structure/closet/crate/secure - containername = "APLU \"Ripley\" Circuit Crate" - access = access_robotics - group = "Engineering" - -/datum/supply_packs/mecha_odysseus - name = "Circuit Crate (\"Odysseus\")" - contains = list(/obj/item/weapon/circuitboard/mecha/odysseus/peripherals, //TEMPORARY due to lack of circuitboard printer - /obj/item/weapon/circuitboard/mecha/odysseus/main) //TEMPORARY due to lack of circuitboard printer - cost = 25 - containertype = /obj/structure/closet/crate/secure - containername = "\"Odysseus\" Circuit Crate" - access = access_robotics - group = "Engineering" - - -/datum/supply_packs/robotics - name = "Robotics Assembly Crate" - contains = list(/obj/item/device/assembly/prox_sensor, - /obj/item/device/assembly/prox_sensor, - /obj/item/device/assembly/prox_sensor, - /obj/item/weapon/storage/toolbox/electrical, - /obj/item/device/flash, - /obj/item/device/flash, - /obj/item/device/flash, - /obj/item/device/flash, - /obj/item/weapon/cell/high, - /obj/item/weapon/cell/high) - cost = 10 - containertype = /obj/structure/closet/crate/secure/gear - containername = "Robotics Assembly" - access = access_robotics - group = "Engineering" - -/datum/supply_packs/plasma - name = "Plasma assembly crate" - contains = list(/obj/item/weapon/tank/plasma, - /obj/item/weapon/tank/plasma, - /obj/item/weapon/tank/plasma, - /obj/item/device/assembly/igniter, - /obj/item/device/assembly/igniter, - /obj/item/device/assembly/igniter, - /obj/item/device/assembly/prox_sensor, - /obj/item/device/assembly/prox_sensor, - /obj/item/device/assembly/prox_sensor, - /obj/item/device/transfer_valve, - /obj/item/device/transfer_valve, - /obj/item/device/transfer_valve, - /obj/item/device/assembly/timer, - /obj/item/device/assembly/timer, - /obj/item/device/assembly/timer) - cost = 10 - containertype = /obj/structure/closet/crate/secure/plasma - containername = "Plasma assembly crate" - access = access_tox_storage - group = "Medical / Science" - -/datum/supply_packs/weapons - name = "Weapons crate" - contains = list(/obj/item/weapon/melee/baton/loaded, - /obj/item/weapon/melee/baton/loaded, - /obj/item/weapon/gun/energy/laser, - /obj/item/weapon/gun/energy/laser, - /obj/item/weapon/gun/energy/advtaser, - /obj/item/weapon/gun/energy/advtaser, - /obj/item/weapon/storage/box/flashbangs, - /obj/item/weapon/storage/box/flashbangs) - cost = 30 - containertype = /obj/structure/closet/crate/secure/weapon - containername = "Weapons crate" - access = access_security - group = "Security" - -/datum/supply_packs/disabler - name = "Disabler Crate" - contains = list(/obj/item/weapon/gun/energy/disabler, - /obj/item/weapon/gun/energy/disabler, - /obj/item/weapon/gun/energy/disabler) - cost = 10 - containertype = /obj/structure/closet/crate/secure/weapon - containername = "disabler crate" - access = access_security - group = "Security" - -/datum/supply_packs/eweapons - name = "Experimental weapons crate" - contains = list(/obj/item/weapon/flamethrower/full, - /obj/item/weapon/tank/plasma, - /obj/item/weapon/tank/plasma, - /obj/item/weapon/tank/plasma, - /obj/item/weapon/grenade/chem_grenade/incendiary, - /obj/item/weapon/grenade/chem_grenade/incendiary, - /obj/item/weapon/grenade/chem_grenade/incendiary) - cost = 25 - containertype = /obj/structure/closet/crate/secure/weapon - containername = "Experimental weapons crate" - access = access_heads - group = "Security" - -/datum/supply_packs/armor - name = "Armor crate" - contains = list(/obj/item/clothing/head/helmet, - /obj/item/clothing/head/helmet, - /obj/item/clothing/suit/armor/vest, - /obj/item/clothing/suit/armor/vest) - cost = 15 - containertype = /obj/structure/closet/crate/secure - containername = "Armor crate" - access = access_security - group = "Security" - -/datum/supply_packs/riot - name = "Riot gear crate" - contains = list(/obj/item/weapon/melee/baton/loaded, - /obj/item/weapon/melee/baton/loaded, - /obj/item/weapon/melee/baton/loaded, - /obj/item/weapon/shield/riot, - /obj/item/weapon/shield/riot, - /obj/item/weapon/shield/riot, - /obj/item/weapon/storage/box/flashbangs, - /obj/item/weapon/storage/box/flashbangs, - /obj/item/weapon/storage/box/flashbangs, - /obj/item/weapon/handcuffs, - /obj/item/weapon/handcuffs, - /obj/item/weapon/handcuffs, - /obj/item/clothing/head/helmet/riot, - /obj/item/clothing/suit/armor/riot, - /obj/item/clothing/head/helmet/riot, - /obj/item/clothing/suit/armor/riot, - /obj/item/clothing/head/helmet/riot, - /obj/item/clothing/suit/armor/riot) - cost = 60 - containertype = /obj/structure/closet/crate/secure - containername = "Riot gear crate" - access = access_armory - group = "Security" - -/datum/supply_packs/loyalty - name = "Loyalty implant crate" - contains = list (/obj/item/weapon/storage/lockbox/loyalty) - cost = 60 - containertype = /obj/structure/closet/crate/secure - containername = "Loyalty implant crate" - access = access_armory - group = "Security" - -/datum/supply_packs/ballistic - name = "Ballistic gear crate" - contains = list(/obj/item/clothing/suit/armor/bulletproof, - /obj/item/clothing/suit/armor/bulletproof, - /obj/item/weapon/storage/belt/bandolier, - /obj/item/weapon/storage/belt/bandolier, - /obj/item/weapon/gun/projectile/shotgun/combat, - /obj/item/weapon/gun/projectile/shotgun/combat) - cost = 50 - containertype = /obj/structure/closet/crate/secure - containername = "Ballistic gear crate" - access = access_armory - group = "Security" - -/datum/supply_packs/shotgunammo - name = "Shotgun shells" - contains = list(/obj/item/ammo_casing/shotgun, - /obj/item/ammo_casing/shotgun, - /obj/item/ammo_casing/shotgun, - /obj/item/ammo_casing/shotgun, - /obj/item/ammo_casing/shotgun, - /obj/item/ammo_casing/shotgun, - /obj/item/ammo_casing/shotgun, - /obj/item/ammo_casing/shotgun, - /obj/item/ammo_casing/shotgun, - /obj/item/ammo_casing/shotgun) - cost = 20 - containertype = /obj/structure/closet/crate/secure - containername = "Shotgun shells" - access = access_armory - group = "Security" - -/datum/supply_packs/expenergy - name = "Experimental energy gear crate" - contains = list(/obj/item/clothing/suit/armor/laserproof, - /obj/item/clothing/suit/armor/laserproof, - /obj/item/weapon/gun/energy/gun, - /obj/item/weapon/gun/energy/gun) - cost = 50 - containertype = /obj/structure/closet/crate/secure - containername = "Experimental energy gear crate" - access = access_armory - group = "Security" - -/datum/supply_packs/exparmor - name = "Experimental armor crate" - contains = list(/obj/item/clothing/suit/armor/laserproof, - /obj/item/clothing/suit/armor/bulletproof, - /obj/item/clothing/head/helmet/riot, - /obj/item/clothing/suit/armor/riot) - cost = 35 - containertype = /obj/structure/closet/crate/secure - containername = "Experimental armor crate" - access = access_armory - group = "Security" - -/datum/supply_packs/securitybarriers - name = "Security Barriers" - contains = list(/obj/machinery/deployable/barrier, - /obj/machinery/deployable/barrier, - /obj/machinery/deployable/barrier, - /obj/machinery/deployable/barrier) - cost = 20 - containertype = /obj/structure/closet/crate/secure/gear - containername = "Security Barriers crate" - group = "Security" - -/datum/supply_packs/securitybarriers - name = "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" - access = access_teleporter - group = "Security" - -/datum/supply_packs/randomised - var/num_contained = 3 //number of items picked to be contained in a randomised crate - contains = list(/obj/item/clothing/head/collectable/chef, - /obj/item/clothing/head/collectable/paper, - /obj/item/clothing/head/collectable/tophat, - /obj/item/clothing/head/collectable/captain, - /obj/item/clothing/head/collectable/beret, - /obj/item/clothing/head/collectable/welding, - /obj/item/clothing/head/collectable/flatcap, - /obj/item/clothing/head/collectable/pirate, - /obj/item/clothing/head/collectable/kitty, - /obj/item/clothing/head/collectable/rabbitears, - /obj/item/clothing/head/collectable/wizard, - /obj/item/clothing/head/collectable/hardhat, - /obj/item/clothing/head/collectable/HoS, - /obj/item/clothing/head/collectable/thunderdome, - /obj/item/clothing/head/collectable/swat, - /obj/item/clothing/head/collectable/slime, - /obj/item/clothing/head/collectable/police, - /obj/item/clothing/head/collectable/slime, - /obj/item/clothing/head/collectable/xenom, - /obj/item/clothing/head/collectable/petehat) - name = "Collectable hat crate!" - cost = 200 - containertype = /obj/structure/closet/crate - containername = "Collectable hats crate! Brought to you by Bass.inc!" - group = "Operations" - -/datum/supply_packs/randomised/New() - manifest += "Contains any [num_contained] of:" - ..() - -/datum/supply_packs/artscrafts - name = "Arts and Crafts supplies" - contains = list(/obj/item/weapon/storage/fancy/crayons, - /obj/item/device/camera, - /obj/item/device/camera_film, - /obj/item/device/camera_film, - /obj/item/weapon/storage/photo_album, - /obj/item/weapon/packageWrap, - /obj/item/weapon/reagent_containers/glass/paint/red, - /obj/item/weapon/reagent_containers/glass/paint/green, - /obj/item/weapon/reagent_containers/glass/paint/blue, - /obj/item/weapon/reagent_containers/glass/paint/yellow, - /obj/item/weapon/reagent_containers/glass/paint/violet, - /obj/item/weapon/reagent_containers/glass/paint/black, - /obj/item/weapon/reagent_containers/glass/paint/white, - /obj/item/weapon/reagent_containers/glass/paint/remover, - /obj/item/weapon/contraband/poster, - /obj/item/weapon/wrapping_paper, - /obj/item/weapon/wrapping_paper, - /obj/item/weapon/wrapping_paper) - cost = 10 - containertype = "/obj/structure/closet/crate" - containername = "Arts and Crafts crate" - group = "Operations" - - -/datum/supply_packs/randomised/contraband - num_contained = 6 - contains = list(/obj/item/weapon/storage/pill_bottle/zoom, - /obj/item/weapon/storage/pill_bottle/happy, - /obj/item/weapon/storage/pill_bottle/random_drug_bottle, - /obj/item/weapon/storage/fancy/cigarettes/dromedaryco, - /obj/item/weapon/storage/fancy/cigarettes/cigpack_shadyjims, - /obj/item/weapon/grenade/smokebomb, - /obj/item/clothing/mask/cigarette/cigar/cohiba, - /obj/item/weapon/reagent_containers/food/drinks/cans/ale, - /obj/item/weapon/reagent_containers/food/drinks/bottle/patron, - /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, - /obj/item/weapon/lipstick/random) - - name = "Contraband crate" - cost = 30 - containertype = /obj/structure/closet/crate - containername = "Unlabeled crate" - contraband = 1 - group = "Operations" - -/datum/supply_packs/boxes - name = "Empty Box supplies" - contains = list(/obj/item/weapon/storage/box, - /obj/item/weapon/storage/box, - /obj/item/weapon/storage/box, - /obj/item/weapon/storage/box, - /obj/item/weapon/storage/box, - /obj/item/weapon/storage/box, - /obj/item/weapon/storage/box, - /obj/item/weapon/storage/box, - /obj/item/weapon/storage/box, - /obj/item/weapon/storage/box) - cost = 10 - containertype = "/obj/structure/closet/crate" - containername = "Empty Box crate" - group = "Operations" - -/datum/supply_packs/surgery - name = "Surgery crate" - contains = list(/obj/item/weapon/cautery, - /obj/item/weapon/surgicaldrill, - /obj/item/clothing/mask/breath/medical, - /obj/item/weapon/tank/anesthetic, - /obj/item/weapon/FixOVein, - /obj/item/weapon/hemostat, - /obj/item/weapon/scalpel, - /obj/item/weapon/bonegel, - /obj/item/weapon/retractor, - /obj/item/weapon/bonesetter, - /obj/item/weapon/circular_saw) - cost = 25 - containertype = "/obj/structure/closet/crate/secure" - containername = "Surgery crate" - access = access_medical - group = "Medical / Science" - -/datum/supply_packs/sterile - name = "Sterile equipment crate" - contains = list(/obj/item/clothing/under/rank/medical/green, - /obj/item/clothing/under/rank/medical/green, - /obj/item/weapon/storage/box/masks, - /obj/item/weapon/storage/box/gloves) - cost = 15 - containertype = "/obj/structure/closet/crate" - containername = "Sterile equipment crate" - group = "Medical / Science" - -/datum/supply_packs/randomised/pizza - num_contained = 5 - contains = list(/obj/item/pizzabox/margherita, - /obj/item/pizzabox/mushroom, - /obj/item/pizzabox/meat, - /obj/item/pizzabox/vegetable) - name = "Surprise pack of five dozen pizzas" - cost = 15 - containertype = /obj/structure/closet/crate/freezer - containername = "Pizza crate" - group = "Hospitality" - -/datum/supply_packs/formal_wear - contains = list(/obj/item/clothing/head/that, - /obj/item/clothing/suit/storage/lawyer/bluejacket, - /obj/item/clothing/suit/storage/lawyer/purpjacket, - /obj/item/clothing/under/suit_jacket, - /obj/item/clothing/under/suit_jacket/female, - /obj/item/clothing/under/suit_jacket/really_black, - /obj/item/clothing/under/suit_jacket/red, - /obj/item/clothing/shoes/black, - /obj/item/clothing/shoes/black, - /obj/item/clothing/suit/wcoat) - name = "Formalwear closet" - cost = 30 - containertype = /obj/structure/closet - containername = "Formalwear for the best occasions." - group = "Operations" -/* -/datum/supply_packs/rust_injector - contains = list(/obj/machinery/power/rust_fuel_injector) - name = "RUST fuel injector" - cost = 50 - containertype = /obj/structure/closet/crate/secure/large - containername = "RUST injector crate" - group = "Engineering" - access = access_engine - -/datum/supply_packs/rust_compressor - contains = list(/obj/item/weapon/module/rust_fuel_compressor) - name = "RUST fuel compressor circuitry" - cost = 60 - containertype = /obj/structure/closet/crate/secure - containername = "RUST fuel compressor circuitry" - group = "Engineering" - access = access_engine - -/datum/supply_packs/rust_assembly_port - contains = list(/obj/item/weapon/module/rust_fuel_port) - name = "RUST fuel assembly port circuitry" - cost = 40 - containertype = /obj/structure/closet/crate/secure - containername = "RUST fuel assembly port circuitry" - group = "Engineering" - access = access_engine - -/datum/supply_packs/rust_core - contains = list(/obj/machinery/power/rust_core) - name = "RUST Tokamak Core" - cost = 75 - containertype = /obj/structure/closet/crate/secure/large - containername = "RUST tokamak crate" - group = "Engineering" - access = access_engine -*/ -/datum/supply_packs/shield_gen - contains = list(/obj/item/weapon/circuitboard/shield_gen) - name = "Experimental shield generator circuitry" - cost = 50 - containertype = /obj/structure/closet/crate/secure - containername = "Experimental shield generator" - group = "Engineering" - access = access_ce - -/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" - cost = 10 - containertype = /obj/structure/closet/crate - containername = "EFTPOS crate" - group = "Operations" - -/datum/supply_packs/teg - contains = list(/obj/machinery/power/generator) - name = "Mark I Thermoelectric Generator" - cost = 75 - containertype = /obj/structure/closet/crate/secure/large - containername = "Mk1 TEG crate" - group = "Engineering" - access = access_engine - -/datum/supply_packs/circulator - contains = list(/obj/machinery/atmospherics/binary/circulator) - name = "Binary atmospheric circulator" - cost = 60 - containertype = /obj/structure/closet/crate/secure/large - containername = "Atmospheric circulator crate" - group = "Engineering" - access = access_engine - -/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 - containertype = /obj/structure/closet/crate/hydroponics - containername = "Beekeeping crate" - access = access_hydroponics - group = "Hydroponics" - -/datum/supply_packs/misc/lasertag - name = "Laser Tag Crate" - contains = list(/obj/item/weapon/gun/energy/laser/redtag, - /obj/item/weapon/gun/energy/laser/redtag, - /obj/item/weapon/gun/energy/laser/redtag, - /obj/item/weapon/gun/energy/laser/bluetag, - /obj/item/weapon/gun/energy/laser/bluetag, - /obj/item/weapon/gun/energy/laser/bluetag, - /obj/item/clothing/suit/redtag, - /obj/item/clothing/suit/redtag, - /obj/item/clothing/suit/redtag, - /obj/item/clothing/suit/bluetag, - /obj/item/clothing/suit/bluetag, - /obj/item/clothing/suit/bluetag, - /obj/item/clothing/head/helmet/redtaghelm, - /obj/item/clothing/head/helmet/bluetaghelm) - cost = 15 - containertype = /obj/structure/closet/crate - containername = "laser tag crate" - group = "Operations" - -/datum/supply_packs/vending - name = "Bartending Supply Crate" - contains = list(/obj/item/weapon/vending_refill/boozeomat, - /obj/item/weapon/vending_refill/boozeomat, - /obj/item/weapon/vending_refill/boozeomat, - /obj/item/weapon/vending_refill/coffee, - /obj/item/weapon/vending_refill/coffee, - /obj/item/weapon/vending_refill/coffee) - cost = 15 - containertype = /obj/structure/closet/crate - containername = "bartending supply crate" - group = "Operations" - -/datum/supply_packs/vending/snack - name = "Snack Supply Crate" - contains = list(/obj/item/weapon/vending_refill/snack, - /obj/item/weapon/vending_refill/snack, - /obj/item/weapon/vending_refill/snack) - cost = 15 - containertype = /obj/structure/closet/crate - containername = "snacks supply crate" - group = "Operations" - -/datum/supply_packs/vending/cola - name = "Softdrinks Supply Crate" - contains = list(/obj/item/weapon/vending_refill/cola, - /obj/item/weapon/vending_refill/cola, - /obj/item/weapon/vending_refill/cola) - cost = 15 - containertype = /obj/structure/closet/crate - containername = "softdrinks supply crate" - group = "Operations" - -/datum/supply_packs/vending/cigarette - name = "Cigarette Supply Crate" - contains = list(/obj/item/weapon/vending_refill/cigarette, - /obj/item/weapon/vending_refill/cigarette, - /obj/item/weapon/vending_refill/cigarette) - cost = 15 - containertype = /obj/structure/closet/crate - containername = "cigarette supply crate" - group = "Operations" - -/datum/supply_packs/autodrobe - name = "Autodrobe Supply crate" - contains = list(/obj/item/weapon/vending_refill/autodrobe, - /obj/item/weapon/vending_refill/autodrobe, - /obj/item/weapon/vending_refill/autodrobe) - cost = 15 - containertype = /obj/structure/closet/crate - containername = "autodrobe supply crate" - group = "Operations" - -/datum/supply_packs/clothingvendor - name = "Clothing Vendor Supply crate" - contains = list(/obj/item/weapon/vending_refill/hatdispenser, - /obj/item/weapon/vending_refill/hatdispenser, - /obj/item/weapon/vending_refill/hatdispenser, - /obj/item/weapon/vending_refill/suitdispenser, - /obj/item/weapon/vending_refill/suitdispenser, - /obj/item/weapon/vending_refill/suitdispenser, - /obj/item/weapon/vending_refill/shoedispenser, - /obj/item/weapon/vending_refill/shoedispenser, - /obj/item/weapon/vending_refill/shoedispenser) - cost = 30 - containertype = /obj/structure/closet/crate - containername = "clothing vendor supply crate" - group = "Operations" - -/datum/supply_packs/mafia - name = "Mafia Supply crate" - contains = list(/obj/item/clothing/suit/browntrenchcoat =1,/obj/item/clothing/suit/blacktrenchcoat =1,/obj/item/clothing/head/fedora/whitefedora =1, - /obj/item/clothing/head/fedora/brownfedora =1,/obj/item/clothing/head/fedora =1,/obj/item/clothing/under/flappers =1,/obj/item/clothing/under/mafia =1,/obj/item/clothing/under/mafia/vest =1,/obj/item/clothing/under/mafia/white =1, - /obj/item/clothing/under/mafia/sue =1,/obj/item/clothing/under/mafia/tan =1, /obj/item/toy/crossbow/tommygun =2) - cost = 15 - containertype = /obj/structure/closet/crate - containername = "mafia supply crate" - group = "Operations" - -/datum/supply_packs/fabric - name = "Fabric crate" - contains = list(/obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric, - /obj/item/weapon/ore/fabric) - cost = 30 - containertype = /obj/structure/closet/crate - containername = "Fabric crate" - group = "Operations" +//SUPPLY PACKS +//NOTE: only secure crate types use the access var (and are lockable) +//NOTE: hidden packs only show up when the computer has been hacked. +//ANOTHER NOTE: Contraband is obtainable through modified supplycomp circuitboards. +//BIG NOTE: Don't add living things to crates, that's bad, it will break the shuttle. +//NEW NOTE: Do NOT set the price of any crates below 7 points. Doing so allows infinite points. + +// Supply Groups +var/const/supply_emergency = 1 +var/const/supply_security = 2 +var/const/supply_engineer = 3 +var/const/supply_medical = 4 +var/const/supply_science = 5 +var/const/supply_organic = 6 +var/const/supply_materials = 7 +var/const/supply_misc = 8 + +var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engineer,supply_medical,supply_science,supply_organic,supply_materials,supply_misc) + +/proc/get_supply_group_name(var/cat) + switch(cat) + if(1) + return "Emergency" + if(2) + return "Security" + if(3) + return "Engineering" + if(4) + return "Medical" + if(5) + return "Science" + if(6) + return "Food & Livestock" + if(7) + return "Raw Materials" + if(8) + return "Miscellaneous" + + +/datum/supply_packs + var/name = null + var/list/contains = list() + var/manifest = "" + var/amount = null + var/cost = null + var/containertype = /obj/structure/closet/crate + var/containername = null + var/access = null + var/hidden = 0 + var/contraband = 0 + var/group = supply_misc + + +/datum/supply_packs/New() + manifest += "
    " + for(var/path in contains) + if(!path) continue + var/atom/movable/AM = path + manifest += "
  • [initial(AM.name)]
  • " + manifest += "
" + +////// Use the sections to keep things tidy please /Malkevin + +////////////////////////////////////////////////////////////////////////////// +//////////////////////////// Emergency /////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +/datum/supply_packs/emergency // Section header - use these to set default supply group and crate type for sections + name = "HEADER" // Use "HEADER" to denote section headers, this is needed for the supply computers to filter them + containertype = /obj/structure/closet/crate/internals + group = supply_emergency + + +/datum/supply_packs/emergency/evac + name = "Emergency equipment" + contains = list(/obj/machinery/bot/floorbot, + /obj/machinery/bot/floorbot, + /obj/machinery/bot/medbot, + /obj/machinery/bot/medbot, + /obj/item/weapon/tank/air, + /obj/item/weapon/tank/air, + /obj/item/weapon/tank/air, + /obj/item/weapon/tank/air, + /obj/item/weapon/tank/air, + /obj/item/clothing/mask/gas, + /obj/item/clothing/mask/gas, + /obj/item/clothing/mask/gas, + /obj/item/clothing/mask/gas, + /obj/item/clothing/mask/gas) + cost = 35 + containertype = /obj/structure/closet/crate/internals + containername = "emergency crate" + group = supply_emergency + +/datum/supply_packs/emergency/internals + name = "Internals Crate" + contains = list(/obj/item/clothing/mask/gas, + /obj/item/clothing/mask/gas, + /obj/item/clothing/mask/gas, + /obj/item/weapon/tank/air, + /obj/item/weapon/tank/air, + /obj/item/weapon/tank/air) + cost = 10 + containername = "internals crate" + +/datum/supply_packs/emergency/firefighting + name = "Firefighting Crate" + contains = list(/obj/item/clothing/suit/fire/firefighter, + /obj/item/clothing/suit/fire/firefighter, + /obj/item/clothing/mask/gas, + /obj/item/clothing/mask/gas, + /obj/item/device/flashlight, + /obj/item/device/flashlight, + /obj/item/weapon/tank/oxygen/red, + /obj/item/weapon/tank/oxygen/red, + /obj/item/weapon/extinguisher, + /obj/item/weapon/extinguisher, + /obj/item/clothing/head/hardhat/red, + /obj/item/clothing/head/hardhat/red) + cost = 10 + containertype = /obj/structure/closet/crate + containername = "firefighting crate" + +/datum/supply_packs/emergency/atmostank + name = "Firefighting Watertank" + contains = list(/obj/item/weapon/watertank/atmos) + cost = 10 + containertype = /obj/structure/closet/crate/secure + containername = "firefighting watertank crate" + access = access_atmospherics + +/datum/supply_packs/emergency/weedcontrol + name = "Weed Control Crate" + contains = list(/obj/item/weapon/scythe, + /obj/item/clothing/mask/gas, + /obj/item/weapon/grenade/chem_grenade/antiweed, + /obj/item/weapon/grenade/chem_grenade/antiweed) + cost = 15 + containertype = /obj/structure/closet/crate/secure/hydrosec + containername = "weed control crate" + access = access_hydroponics + +/datum/supply_packs/emergency/specialops + name = "Special Ops supplies" + contains = list(/obj/item/weapon/storage/box/emps, + /obj/item/weapon/grenade/smokebomb, + /obj/item/weapon/grenade/smokebomb, + /obj/item/weapon/grenade/smokebomb, + /obj/item/weapon/pen/sleepy, + /obj/item/weapon/grenade/chem_grenade/incendiary) + cost = 20 + containertype = /obj/structure/closet/crate + containername = "special ops crate" + hidden = 1 + +/datum/supply_packs/emergency/syndicate + name = "ERROR_NULL_ENTRY" + contains = list(/obj/item/weapon/storage/box/syndicate) + cost = 140 + containertype = /obj/structure/closet/crate + containername = "crate" + hidden = 1 + +////////////////////////////////////////////////////////////////////////////// +//////////////////////////// Security //////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +/datum/supply_packs/security + name = "HEADER" + containertype = /obj/structure/closet/crate/secure/gear + access = access_security + group = supply_security + + +/datum/supply_packs/security/supplies + name = "Security Supplies Crate" + contains = list(/obj/item/weapon/storage/box/flashbangs, + /obj/item/weapon/storage/box/teargas, + /obj/item/weapon/storage/box/flashes, + /obj/item/weapon/storage/box/handcuffs) + cost = 10 + containername = "security supply crate" + +////// Armor: Basic + +/datum/supply_packs/security/helmets + name = "Helmets Crate" + contains = list(/obj/item/clothing/head/helmet, + /obj/item/clothing/head/helmet, + /obj/item/clothing/head/helmet) + cost = 10 + containername = "helmet crate" + +/datum/supply_packs/security/armor + name = "Armor Crate" + contains = list(/obj/item/clothing/suit/armor/vest, + /obj/item/clothing/suit/armor/vest, + /obj/item/clothing/suit/armor/vest) + cost = 10 + containername = "armor crate" + +////// Weapons: Basic + +/datum/supply_packs/security/baton + name = "Stun Batons Crate" + contains = list(/obj/item/weapon/melee/baton/loaded, + /obj/item/weapon/melee/baton/loaded, + /obj/item/weapon/melee/baton/loaded) + cost = 10 + containername = "stun baton crate" + +/datum/supply_packs/security/laser + name = "Lasers Crate" + contains = list(/obj/item/weapon/gun/energy/laser, + /obj/item/weapon/gun/energy/laser, + /obj/item/weapon/gun/energy/laser) + cost = 15 + containername = "laser crate" + +/datum/supply_packs/security/taser + name = "Stun Guns Crate" + contains = list(/obj/item/weapon/gun/energy/advtaser, + /obj/item/weapon/gun/energy/advtaser, + /obj/item/weapon/gun/energy/advtaser) + cost = 15 + containername = "stun gun crate" + +/datum/supply_packs/security/disabler + name = "Disabler Crate" + contains = list(/obj/item/weapon/gun/energy/disabler, + /obj/item/weapon/gun/energy/disabler, + /obj/item/weapon/gun/energy/disabler) + cost = 10 + containername = "disabler crate" + +///// Armory stuff + +/datum/supply_packs/security/armory + name = "HEADER" + containertype = /obj/structure/closet/crate/secure/weapon + access = access_armory + +///// Armor: Specialist + +/datum/supply_packs/security/armory/riothelmets + name = "Riot Helmets Crate" + contains = list(/obj/item/clothing/head/helmet/riot, + /obj/item/clothing/head/helmet/riot, + /obj/item/clothing/head/helmet/riot) + cost = 15 + containername = "riot helmets crate" + +/datum/supply_packs/security/armory/riotarmor + name = "Riot Armor Crate" + contains = list(/obj/item/clothing/suit/armor/riot, + /obj/item/clothing/suit/armor/riot, + /obj/item/clothing/suit/armor/riot) + cost = 15 + containername = "riot armor crate" + +/datum/supply_packs/security/armory/riotshields + name = "Riot Shields Crate" + contains = list(/obj/item/weapon/shield/riot, + /obj/item/weapon/shield/riot, + /obj/item/weapon/shield/riot) + cost = 20 + containername = "riot shields crate" + +/datum/supply_packs/security/bullethelmets + name = "Bulletproof Helmets Crate" + contains = list(/obj/item/clothing/head/helmet/alt, + /obj/item/clothing/head/helmet/alt, + /obj/item/clothing/head/helmet/alt) + cost = 10 + containername = "bulletproof helmet crate" + +/datum/supply_packs/security/armory/bulletarmor + name = "Bulletproof Armor Crate" + contains = list(/obj/item/clothing/suit/armor/bulletproof, + /obj/item/clothing/suit/armor/bulletproof, + /obj/item/clothing/suit/armor/bulletproof) + cost = 15 + containername = "tactical armor crate" + +/datum/supply_packs/security/armory/laserarmor + name = "Ablative Armor Crate" + contains = list(/obj/item/clothing/suit/armor/laserproof, + /obj/item/clothing/suit/armor/laserproof) // Only two vests to keep costs down for balance + cost = 20 + containertype = /obj/structure/closet/crate/secure/plasma + containername = "ablative armor crate" + +/////// Weapons: Specialist + +/datum/supply_packs/security/armory/ballistic + name = "Combat Shotguns Crate" + contains = list(/obj/item/weapon/gun/projectile/shotgun/combat, + /obj/item/weapon/gun/projectile/shotgun/combat, + /obj/item/weapon/gun/projectile/shotgun/combat, + /obj/item/weapon/storage/belt/bandolier, + /obj/item/weapon/storage/belt/bandolier, + /obj/item/weapon/storage/belt/bandolier) + cost = 20 + containername = "combat shotgun crate" + +/datum/supply_packs/security/armory/expenergy + name = "Energy Guns Crate" + contains = list(/obj/item/weapon/gun/energy/gun, + /obj/item/weapon/gun/energy/gun) // Only two guns to keep costs down + cost = 25 + containertype = /obj/structure/closet/crate/secure/plasma + containername = "energy gun crate" + +/datum/supply_packs/security/armory/eweapons + name = "Incendiary Weapons Crate" + contains = list(/obj/item/weapon/flamethrower/full, + /obj/item/weapon/tank/plasma, + /obj/item/weapon/tank/plasma, + /obj/item/weapon/tank/plasma, + /obj/item/weapon/grenade/chem_grenade/incendiary, + /obj/item/weapon/grenade/chem_grenade/incendiary, + /obj/item/weapon/grenade/chem_grenade/incendiary) + cost = 15 // its a fecking flamethrower and some plasma, why the shit did this cost so much before!? + containertype = /obj/structure/closet/crate/secure/plasma + containername = "incendiary weapons crate" + access = access_heads + +/////// Implants & etc + +/datum/supply_packs/security/armory/loyalty + name = "Loyalty Implants Crate" + contains = list (/obj/item/weapon/storage/lockbox/loyalty) + cost = 40 + containername = "loyalty implant crate" + +/datum/supply_packs/security/armory/trackingimp + name = "Tracking Implants Crate" + contains = list (/obj/item/weapon/storage/box/trackimp) + cost = 20 + containername = "tracking implant crate" + +/datum/supply_packs/security/armory/chemimp + name = "Chemical Implants Crate" + contains = list (/obj/item/weapon/storage/box/chemimp) + cost = 20 + containername = "chemical implant crate" + +/datum/supply_packs/security/armory/exileimp + name = "Exile Implants Crate" + contains = list (/obj/item/weapon/storage/box/exileimp) + cost = 30 + containername = "exile implant crate" + +/datum/supply_packs/security/securitybarriers + name = "Security Barriers Crate" + contains = list(/obj/machinery/deployable/barrier, + /obj/machinery/deployable/barrier, + /obj/machinery/deployable/barrier, + /obj/machinery/deployable/barrier) + cost = 20 + containername = "security barriers crate" + +/datum/supply_packs/security/securityclothes + name = "Security Clothing Crate" + contains = list(/obj/item/clothing/under/rank/security/corp, + /obj/item/clothing/under/rank/security/corp, + /obj/item/clothing/head/soft/sec/corp, + /obj/item/clothing/head/soft/sec/corp, + /obj/item/clothing/under/rank/warden/corp, + /obj/item/clothing/head/beret/sec/warden, + /obj/item/clothing/under/rank/head_of_security/corp, + /obj/item/clothing/head/HoS/beret) + cost = 30 + containername = "security clothing crate" + + +////////////////////////////////////////////////////////////////////////////// +//////////////////////////// Engineering ///////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +/datum/supply_packs/engineering + name = "HEADER" + group = supply_engineer + + +/datum/supply_packs/engineering/fueltank + name = "Fuel Tank Crate" + contains = list(/obj/structure/reagent_dispensers/fueltank) + cost = 8 + containertype = /obj/structure/largecrate + containername = "fuel tank crate" + +/datum/supply_packs/engineering/tools //the most robust crate + name = "Toolbox Crate" + contains = list(/obj/item/weapon/storage/toolbox/electrical, + /obj/item/weapon/storage/toolbox/electrical, + /obj/item/weapon/storage/toolbox/mechanical, + /obj/item/weapon/storage/toolbox/electrical, + /obj/item/weapon/storage/toolbox/mechanical, + /obj/item/weapon/storage/toolbox/mechanical) + cost = 10 + containername = "electrical maintenance crate" + +/datum/supply_packs/engineering/powergamermitts + name = "Insulated Gloves Crate" + contains = list(/obj/item/clothing/gloves/yellow, + /obj/item/clothing/gloves/yellow, + /obj/item/clothing/gloves/yellow) + cost = 20 //Made of pure-grade bullshittinium + containername = "insulated gloves crate" + +/datum/supply_packs/engineering/power + name = "Powercell Crate" + contains = list(/obj/item/weapon/stock_parts/cell/high, //Changed to an extra high powercell because normal cells are useless + /obj/item/weapon/stock_parts/cell/high, + /obj/item/weapon/stock_parts/cell/high) + cost = 10 + containername = "electrical maintenance crate" + +/datum/supply_packs/engineering/engiequipment + name = "Engineering Gear Crate" + contains = list(/obj/item/weapon/storage/belt/utility, + /obj/item/weapon/storage/belt/utility, + /obj/item/weapon/storage/belt/utility, + /obj/item/clothing/suit/storage/hazardvest, + /obj/item/clothing/suit/storage/hazardvest, + /obj/item/clothing/suit/storage/hazardvest, + /obj/item/clothing/head/welding, + /obj/item/clothing/head/welding, + /obj/item/clothing/head/welding, + /obj/item/clothing/head/hardhat, + /obj/item/clothing/head/hardhat, + /obj/item/clothing/head/hardhat) + cost = 10 + containername = "engineering gear crate" + +/datum/supply_packs/engineering/solar + name = "Solar Pack Crate" + contains = list(/obj/item/solar_assembly, + /obj/item/solar_assembly, + /obj/item/solar_assembly, + /obj/item/solar_assembly, + /obj/item/solar_assembly, + /obj/item/solar_assembly, + /obj/item/solar_assembly, + /obj/item/solar_assembly, + /obj/item/solar_assembly, + /obj/item/solar_assembly, + /obj/item/solar_assembly, + /obj/item/solar_assembly, + /obj/item/solar_assembly, + /obj/item/solar_assembly, + /obj/item/solar_assembly, + /obj/item/solar_assembly, + /obj/item/solar_assembly, + /obj/item/solar_assembly, + /obj/item/solar_assembly, + /obj/item/solar_assembly, + /obj/item/solar_assembly, // 21 Solar Assemblies. 1 Extra for the controller + /obj/item/weapon/circuitboard/solar_control, + /obj/item/weapon/tracker_electronics, + /obj/item/weapon/paper/solar) + cost = 20 + containername = "solar pack crate" + +/datum/supply_packs/engineering/engine + name = "Emitter Crate" + contains = list(/obj/machinery/power/emitter, + /obj/machinery/power/emitter) + cost = 10 + containertype = /obj/structure/closet/crate/secure + containername = "emitter crate" + access = access_ce + +/datum/supply_packs/engineering/engine/field_gen + name = "Field Generator Crate" + contains = list(/obj/machinery/field_generator, + /obj/machinery/field_generator) + cost = 10 + containername = "field generator crate" + +/datum/supply_packs/engineering/engine/sing_gen + name = "Singularity Generator Crate" + contains = list(/obj/machinery/the_singularitygen) + cost = 10 + containername = "singularity generator crate" + +/datum/supply_packs/engineering/engine/collector + name = "Collector Crate" + contains = list(/obj/machinery/power/rad_collector, + /obj/machinery/power/rad_collector, + /obj/machinery/power/rad_collector) + cost = 10 + containername = "collector crate" + +/datum/supply_packs/engineering/engine/PA + name = "Particle Accelerator Crate" + contains = list(/obj/structure/particle_accelerator/fuel_chamber, + /obj/machinery/particle_accelerator/control_box, + /obj/structure/particle_accelerator/particle_emitter/center, + /obj/structure/particle_accelerator/particle_emitter/left, + /obj/structure/particle_accelerator/particle_emitter/right, + /obj/structure/particle_accelerator/power_box, + /obj/structure/particle_accelerator/end_cap) + cost = 25 + containername = "particle accelerator crate" + +/datum/supply_packs/engineering/engine/spacesuit + name = "Space Suit Crate" + contains = list(/obj/item/clothing/suit/space, + /obj/item/clothing/head/helmet/space, + /obj/item/clothing/mask/breath,) + cost = 80 + containertype = /obj/structure/closet/crate/secure + containername = "space suit crate" + access = access_eva + +/datum/supply_packs/engineering/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 + containername = "Inflatable Barrier Crate" + +////////////////////////////////////////////////////////////////////////////// +//////////////////////////// Medical ///////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +/datum/supply_packs/medical + name = "HEADER" + containertype = /obj/structure/closet/crate/medical + group = supply_medical + + +/datum/supply_packs/medical/supplies + name = "Medical Supplies Crate" + contains = list(/obj/item/weapon/reagent_containers/glass/bottle/antitoxin, + /obj/item/weapon/reagent_containers/glass/bottle/antitoxin, + /obj/item/weapon/reagent_containers/glass/bottle/inaprovaline, + /obj/item/weapon/reagent_containers/glass/bottle/inaprovaline, + /obj/item/weapon/reagent_containers/glass/bottle/stoxin, + /obj/item/weapon/reagent_containers/glass/bottle/stoxin, + /obj/item/weapon/reagent_containers/glass/bottle/toxin, + /obj/item/weapon/reagent_containers/glass/bottle/toxin, + /obj/item/weapon/reagent_containers/glass/beaker/large, + /obj/item/weapon/reagent_containers/glass/beaker/large, + /obj/item/stack/medical/bruise_pack, + /obj/item/weapon/storage/box/beakers, + /obj/item/weapon/storage/box/syringes, + /obj/item/weapon/storage/box/bodybags) + cost = 20 + containertype = /obj/structure/closet/crate/medical + containername = "medical supplies crate" + +/datum/supply_packs/medical/firstaid + name = "First Aid Kits Crate" + contains = list(/obj/item/weapon/storage/firstaid/regular, + /obj/item/weapon/storage/firstaid/regular, + /obj/item/weapon/storage/firstaid/regular, + /obj/item/weapon/storage/firstaid/regular) + cost = 10 + containername = "first aid kits crate" + +/datum/supply_packs/medical/firstaidadv + name = "Advaced First Aid Kits Crate" + contains = list(/obj/item/weapon/storage/firstaid/adv, + /obj/item/weapon/storage/firstaid/adv, + /obj/item/weapon/storage/firstaid/adv, + /obj/item/weapon/storage/firstaid/adv) + cost = 10 + containername = "advaced first aid kits crate" + +/datum/supply_packs/medical/firstaidburns + name = "Burns Treatment Kits Crate" + contains = list(/obj/item/weapon/storage/firstaid/fire, + /obj/item/weapon/storage/firstaid/fire, + /obj/item/weapon/storage/firstaid/fire) + cost = 10 + containername = "fire first aid kits crate" + +/datum/supply_packs/medical/firstaidtoxins + name = "Toxin Treatment Kits Crate" + contains = list(/obj/item/weapon/storage/firstaid/toxin, + /obj/item/weapon/storage/firstaid/toxin, + /obj/item/weapon/storage/firstaid/toxin) + cost = 10 + containername = "toxin first aid kits crate" + +/datum/supply_packs/medical/firstaidoxygen + name = "Oxygen Deprivation Kits Crate" + contains = list(/obj/item/weapon/storage/firstaid/o2, + /obj/item/weapon/storage/firstaid/o2, + /obj/item/weapon/storage/firstaid/o2) + cost = 10 + containername = "oxygen deprivation kits crate" + + +/datum/supply_packs/medical/virus + name = "Virus Crate" + contains = list(/obj/item/weapon/virusdish/random, + /obj/item/weapon/virusdish/random, + /obj/item/weapon/virusdish/random, + /obj/item/weapon/virusdish/random) + cost = 25 + containertype = /obj/structure/closet/crate/secure/plasma + containername = "virus crate" + access = access_cmo + + +/datum/supply_packs/medical/bloodpacks + name = "Blood Pack Variety Crate" + contains = list(/obj/item/weapon/reagent_containers/blood/empty, + /obj/item/weapon/reagent_containers/blood/empty, + /obj/item/weapon/reagent_containers/blood/APlus, + /obj/item/weapon/reagent_containers/blood/AMinus, + /obj/item/weapon/reagent_containers/blood/BPlus, + /obj/item/weapon/reagent_containers/blood/BMinus, + /obj/item/weapon/reagent_containers/blood/OPlus, + /obj/item/weapon/reagent_containers/blood/OMinus) + cost = 35 + containertype = /obj/structure/closet/crate/freezer + containername = "blood pack crate" + +/datum/supply_packs/medical/iv_drip + name = "IV Drip Crate" + contains = list(/obj/machinery/iv_drip) + cost = 30 + containertype = /obj/structure/closet/crate/secure + containername = "iv drip crate" + access = access_cmo + +/datum/supply_packs/medical/surgery + name = "Surgery crate" + contains = list(/obj/item/weapon/cautery, + /obj/item/weapon/surgicaldrill, + /obj/item/clothing/mask/breath/medical, + /obj/item/weapon/tank/anesthetic, + /obj/item/weapon/FixOVein, + /obj/item/weapon/hemostat, + /obj/item/weapon/scalpel, + /obj/item/weapon/bonegel, + /obj/item/weapon/retractor, + /obj/item/weapon/bonesetter, + /obj/item/weapon/circular_saw) + cost = 25 + containertype = /obj/structure/closet/crate/secure + containername = "Surgery crate" + access = access_medical + + +////////////////////////////////////////////////////////////////////////////// +//////////////////////////// Science ///////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +/datum/supply_packs/science + name = "HEADER" + group = supply_science + + +/datum/supply_packs/science/robotics + name = "Robotics Assembly Crate" + contains = list(/obj/item/device/assembly/prox_sensor, + /obj/item/device/assembly/prox_sensor, + /obj/item/device/assembly/prox_sensor, + /obj/item/weapon/storage/toolbox/electrical, + /obj/item/weapon/storage/box/flashes, + /obj/item/weapon/stock_parts/cell/high, + /obj/item/weapon/stock_parts/cell/high) + cost = 10 + containertype = /obj/structure/closet/crate/secure + containername = "robotics assembly crate" + access = access_robotics + +/datum/supply_packs/science/robotics/mecha_ripley + name = "Circuit Crate (\"Ripley\" APLU)" + contains = list(/obj/item/weapon/book/manual/ripley_build_and_repair, + /obj/item/weapon/circuitboard/mecha/ripley/main, //TEMPORARY due to lack of circuitboard printer + /obj/item/weapon/circuitboard/mecha/ripley/peripherals) //TEMPORARY due to lack of circuitboard printer + cost = 30 + containertype = /obj/structure/closet/crate/secure + containername = "\improper APLU \"Ripley\" circuit crate" + +/datum/supply_packs/science/robotics/mecha_odysseus + name = "Circuit Crate (\"Odysseus\")" + contains = list(/obj/item/weapon/circuitboard/mecha/odysseus/peripherals, //TEMPORARY due to lack of circuitboard printer + /obj/item/weapon/circuitboard/mecha/odysseus/main) //TEMPORARY due to lack of circuitboard printer + cost = 25 + containertype = /obj/structure/closet/crate/secure + containername = "\improper \"Odysseus\" circuit crate" + +/datum/supply_packs/science/plasma + name = "Plasma Assembly Crate" + contains = list(/obj/item/weapon/tank/plasma, + /obj/item/weapon/tank/plasma, + /obj/item/weapon/tank/plasma, + /obj/item/device/assembly/igniter, + /obj/item/device/assembly/igniter, + /obj/item/device/assembly/igniter, + /obj/item/device/assembly/prox_sensor, + /obj/item/device/assembly/prox_sensor, + /obj/item/device/assembly/prox_sensor, + /obj/item/device/assembly/timer, + /obj/item/device/assembly/timer, + /obj/item/device/assembly/timer) + cost = 10 + containertype = /obj/structure/closet/crate/secure/plasma + containername = "plasma assembly crate" + access = access_tox_storage + group = supply_science + +/datum/supply_packs/science/shieldwalls + name = "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" + access = access_teleporter + + +/datum/supply_packs/science/transfer_valves + name = "Tank Transfer Valves" + contains = list(/obj/item/device/transfer_valve, + /obj/item/device/transfer_valve) + cost = 60 + containertype = /obj/structure/closet/crate/secure + containername = "transfer valves crate" + access = access_rd + + +////////////////////////////////////////////////////////////////////////////// +//////////////////////////// Organic ///////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +/datum/supply_packs/organic + name = "HEADER" + group = supply_organic + containertype = /obj/structure/closet/crate/freezer + + +/datum/supply_packs/organic/food + name = "Food Crate" + contains = list(/obj/item/weapon/reagent_containers/food/snacks/flour, + /obj/item/weapon/reagent_containers/food/snacks/flour, + /obj/item/weapon/reagent_containers/food/snacks/flour, + /obj/item/weapon/reagent_containers/food/snacks/flour, + /obj/item/weapon/reagent_containers/food/drinks/milk, + /obj/item/weapon/reagent_containers/food/drinks/soymilk, + /obj/item/weapon/storage/fancy/egg_box, + /obj/item/weapon/reagent_containers/food/condiment/enzyme, + /obj/item/weapon/reagent_containers/food/condiment/sugar, + /obj/item/weapon/reagent_containers/food/snacks/meat/monkey, + /obj/item/weapon/reagent_containers/food/snacks/grown/banana, + /obj/item/weapon/reagent_containers/food/snacks/grown/banana, + /obj/item/weapon/reagent_containers/food/snacks/grown/banana) + cost = 10 + containername = "food crate" + +/datum/supply_packs/organic/pizza + name = "Pizza Crate" + contains = list(/obj/item/pizzabox/margherita, + /obj/item/pizzabox/mushroom, + /obj/item/pizzabox/meat, + /obj/item/pizzabox/vegetable) + cost = 60 + containername = "Pizza crate" + +/datum/supply_packs/organic/monkey + name = "Monkey Crate" + contains = list (/obj/item/weapon/storage/box/monkeycubes) + cost = 20 + containername = "monkey crate" + +/datum/supply_packs/organic/farwa + name = "Farwa crate" + contains = list (/obj/item/weapon/storage/box/farwacubes) + cost = 30 + containername = "farwa crate" + +/datum/supply_packs/organic/skrell + name = "Neaera crate" + contains = list (/obj/item/weapon/storage/box/neaeracubes) + cost = 30 + containername = "neaera crate" + +/datum/supply_packs/organic/stok + name = "Stok crate" + contains = list (/obj/item/weapon/storage/box/stokcubes) + cost = 30 + containername = "stok crate" + +/datum/supply_packs/organic/party + name = "Party equipment" + contains = list(/obj/item/weapon/storage/box/drinkingglasses, + /obj/item/weapon/reagent_containers/food/drinks/shaker, + /obj/item/weapon/reagent_containers/food/drinks/bottle/patron, + /obj/item/weapon/reagent_containers/food/drinks/bottle/goldschlager, + /obj/item/weapon/reagent_containers/food/drinks/cans/ale, + /obj/item/weapon/reagent_containers/food/drinks/cans/ale, + /obj/item/weapon/reagent_containers/food/drinks/cans/beer, + /obj/item/weapon/reagent_containers/food/drinks/cans/beer, + /obj/item/weapon/reagent_containers/food/drinks/cans/beer, + /obj/item/weapon/reagent_containers/food/drinks/cans/beer) + cost = 20 + containername = "party equipment" + +//////// livestock +/datum/supply_packs/organic/cow + name = "Cow Crate" + cost = 30 + containertype = /obj/structure/closet/critter/cow + containername = "cow crate" + +/datum/supply_packs/organic/goat + name = "Goat Crate" + cost = 25 + containertype = /obj/structure/closet/critter/goat + containername = "goat crate" + +/datum/supply_packs/organic/chicken + name = "Chicken Crate" + cost = 20 + containertype = /obj/structure/closet/critter/chick + containername = "chicken crate" + +/datum/supply_packs/organic/corgi + name = "Corgi Crate" + cost = 50 + containertype = /obj/structure/closet/critter/corgi + containername = "corgi crate" + +/datum/supply_packs/organic/cat + name = "Cat Crate" + cost = 50 //Cats are worth as much as corgis. + containertype = /obj/structure/closet/critter/cat + containername = "cat crate" + +/datum/supply_packs/organic/pug + name = "Pug Crate" + cost = 50 + containertype = /obj/structure/closet/critter/pug + containername = "pug crate" + +/datum/supply_packs/organic/fox + name = "Fox Crate" + cost = 55 //Foxes are cool. + containertype = /obj/structure/closet/critter/fox + containername = "fox crate" + +/datum/supply_packs/organic/butterfly + name = "Butterflies Crate" + cost = 50 + containertype = /obj/structure/closet/critter/butterfly + containername = "butterflies crate" + contraband = 1 + +////// hippy gear + +/datum/supply_packs/organic/hydroponics // -- Skie + name = "Hydroponics Supply Crate" + contains = list(/obj/item/weapon/reagent_containers/spray/plantbgone, + /obj/item/weapon/reagent_containers/spray/plantbgone, + /obj/item/weapon/reagent_containers/glass/bottle/ammonia, + /obj/item/weapon/reagent_containers/glass/bottle/ammonia, + /obj/item/weapon/hatchet, + /obj/item/weapon/minihoe, + /obj/item/device/analyzer/plant_analyzer, + /obj/item/clothing/gloves/botanic_leather, + /obj/item/clothing/suit/apron) // Updated with new things + cost = 15 + containertype = /obj/structure/closet/crate/hydroponics + containername = "hydroponics crate" + +/datum/supply_packs/misc/hydroponics/hydrotank + name = "Hydroponics Watertank Backpack Crate" + contains = list(/obj/item/weapon/watertank) + cost = 10 + containertype = /obj/structure/closet/crate/secure + containername = "hydroponics watertank crate" + access = access_hydroponics + +/datum/supply_packs/organic/hydroponics/seeds + name = "Seeds Crate" + contains = list(/obj/item/seeds/chiliseed, + /obj/item/seeds/berryseed, + /obj/item/seeds/cornseed, + /obj/item/seeds/eggplantseed, + /obj/item/seeds/tomatoseed, + /obj/item/seeds/soyaseed, + /obj/item/seeds/wheatseed, + /obj/item/seeds/carrotseed, + /obj/item/seeds/sunflowerseed, + /obj/item/seeds/chantermycelium, + /obj/item/seeds/potatoseed, + /obj/item/seeds/sugarcaneseed) + cost = 10 + containername = "seeds crate" + +/datum/supply_packs/organic/hydroponics/exoticseeds + name = "Exotic Seeds Crate" + contains = list(/obj/item/seeds/nettleseed, + /obj/item/seeds/replicapod, + /obj/item/seeds/replicapod, + /obj/item/seeds/replicapod, + /obj/item/seeds/plumpmycelium, + /obj/item/seeds/libertymycelium, + /obj/item/seeds/amanitamycelium, + /obj/item/seeds/reishimycelium, + /obj/item/seeds/bananaseed, + /obj/item/seeds/eggyseed) + cost = 15 + containername = "exotic seeds crate" + +/datum/supply_packs/organic/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 + containertype = /obj/structure/closet/crate/hydroponics + containername = "Beekeeping crate" + access = access_hydroponics + +/datum/supply_packs/organic/vending + name = "Bartending Supply Crate" + contains = list(/obj/item/weapon/vending_refill/boozeomat, + /obj/item/weapon/vending_refill/boozeomat, + /obj/item/weapon/vending_refill/boozeomat, + /obj/item/weapon/vending_refill/coffee, + /obj/item/weapon/vending_refill/coffee, + /obj/item/weapon/vending_refill/coffee) + cost = 20 + containername = "bartending supply crate" + +/datum/supply_packs/organic/foodcart + name = "Food Cart crate" + contains = list(/obj/structure/foodcart) + cost = 10 + containertype = /obj/structure/largecrate + containername = "food cart crate" + +/datum/supply_packs/organic/vending/snack + name = "Snack Supply Crate" + contains = list(/obj/item/weapon/vending_refill/snack, + /obj/item/weapon/vending_refill/snack, + /obj/item/weapon/vending_refill/snack) + cost = 15 + containername = "snacks supply crate" + +/datum/supply_packs/organic/vending/cola + name = "Softdrinks Supply Crate" + contains = list(/obj/item/weapon/vending_refill/cola, + /obj/item/weapon/vending_refill/cola, + /obj/item/weapon/vending_refill/cola) + cost = 15 + containername = "softdrinks supply crate" + +/datum/supply_packs/organic/vending/cigarette + name = "Cigarette Supply Crate" + contains = list(/obj/item/weapon/vending_refill/cigarette, + /obj/item/weapon/vending_refill/cigarette, + /obj/item/weapon/vending_refill/cigarette) + cost = 15 + containername = "cigarette supply crate" + +////////////////////////////////////////////////////////////////////////////// +//////////////////////////// Materials /////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +/datum/supply_packs/materials + name = "HEADER" + group = supply_materials + + +/datum/supply_packs/materials/metal50 + name = "50 Metal Sheets" + contains = list(/obj/item/stack/sheet/metal) + amount = 50 + cost = 10 + containername = "metal sheets crate" + +/datum/supply_packs/materials/plasteel20 + name = "20 Plasteel Sheets" + contains = list(/obj/item/stack/sheet/plasteel) + amount = 20 + cost = 30 + containername = "plasteel sheets crate" + +/datum/supply_packs/materials/plasteel50 + name = "50 Plasteel Sheets" + contains = list(/obj/item/stack/sheet/plasteel) + amount = 50 + cost = 50 + containername = "plasteel sheets crate" + +/datum/supply_packs/materials/glass50 + name = "50 Glass Sheets" + contains = list(/obj/item/stack/sheet/glass) + amount = 50 + cost = 10 + containername = "glass sheets crate" + +/datum/supply_packs/materials/cardboard50 + name = "50 Cardboard Sheets" + contains = list(/obj/item/stack/sheet/cardboard) + amount = 50 + cost = 10 + containername = "cardboard sheets crate" + +/datum/supply_packs/materials/sandstone30 + name = "30 Sandstone Blocks" + contains = list(/obj/item/stack/sheet/mineral/sandstone) + amount = 30 + cost = 20 + containername = "sandstone blocks crate" + + +////////////////////////////////////////////////////////////////////////////// +//////////////////////////// Miscellaneous /////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +/datum/supply_packs/misc + name = "HEADER" + group = supply_misc + +/datum/supply_packs/misc/mule + name = "MULEbot Crate" + contains = list(/obj/machinery/bot/mulebot) + cost = 20 + containertype = /obj/structure/largecrate/mule + containername = "\improper MULEbot Crate" + +/datum/supply_packs/misc/watertank + name = "Water Tank Crate" + contains = list(/obj/structure/reagent_dispensers/watertank) + cost = 8 + containertype = /obj/structure/largecrate + containername = "water tank crate" + +/datum/supply_packs/misc/lasertag + name = "Laser Tag Crate" + contains = list(/obj/item/weapon/gun/energy/laser/redtag, + /obj/item/weapon/gun/energy/laser/redtag, + /obj/item/weapon/gun/energy/laser/redtag, + /obj/item/weapon/gun/energy/laser/bluetag, + /obj/item/weapon/gun/energy/laser/bluetag, + /obj/item/weapon/gun/energy/laser/bluetag, + /obj/item/clothing/suit/redtag, + /obj/item/clothing/suit/redtag, + /obj/item/clothing/suit/redtag, + /obj/item/clothing/suit/bluetag, + /obj/item/clothing/suit/bluetag, + /obj/item/clothing/suit/bluetag, + /obj/item/clothing/head/helmet/redtaghelm, + /obj/item/clothing/head/helmet/bluetaghelm) + cost = 15 + containername = "laser tag crate" + +/datum/supply_packs/misc/religious_supplies + name = "Religious Supplies Crate" + contains = list(/obj/item/weapon/reagent_containers/food/drinks/bottle/holywater, + /obj/item/weapon/reagent_containers/food/drinks/bottle/holywater, + /obj/item/weapon/storage/bible/booze, + /obj/item/weapon/storage/bible/booze, + /obj/item/clothing/suit/chaplain_hoodie, + /obj/item/clothing/head/chaplain_hood, + /obj/item/clothing/suit/chaplain_hoodie, + /obj/item/clothing/head/chaplain_hood) + cost = 40 + containername = "religious supplies crate" + + +///////////// Paper Work + +/datum/supply_packs/misc/paper + name = "Bureaucracy Crate" + contains = list(/obj/structure/filingcabinet/chestdrawer, + /obj/item/device/camera_film, + /obj/item/weapon/hand_labeler, + /obj/item/weapon/paper_bin, + /obj/item/weapon/pen, + /obj/item/weapon/pen/blue, + /obj/item/weapon/pen/red, + /obj/item/weapon/folder/blue, + /obj/item/weapon/folder/red, + /obj/item/weapon/folder/yellow, + /obj/item/weapon/clipboard, + /obj/item/weapon/clipboard) + cost = 15 + containername = "bureaucracy crate" + +/datum/supply_packs/misc/toner + name = "Toner Cartridges crate" + contains = list(/obj/item/device/toner, + /obj/item/device/toner, + /obj/item/device/toner, + /obj/item/device/toner, + /obj/item/device/toner, + /obj/item/device/toner) + cost = 10 + containername = "toner cartridges crate" + +/datum/supply_packs/misc/artscrafts + name = "Arts and Crafts supplies" + contains = list(/obj/item/weapon/storage/fancy/crayons, + /obj/item/device/camera, + /obj/item/device/camera_film, + /obj/item/device/camera_film, + /obj/item/weapon/storage/photo_album, + /obj/item/stack/packageWrap, + /obj/item/weapon/reagent_containers/glass/paint/red, + /obj/item/weapon/reagent_containers/glass/paint/green, + /obj/item/weapon/reagent_containers/glass/paint/blue, + /obj/item/weapon/reagent_containers/glass/paint/yellow, + /obj/item/weapon/reagent_containers/glass/paint/violet, + /obj/item/weapon/reagent_containers/glass/paint/black, + /obj/item/weapon/reagent_containers/glass/paint/white, + /obj/item/weapon/reagent_containers/glass/paint/remover, + /obj/item/weapon/contraband/poster, + /obj/item/stack/wrapping_paper, + /obj/item/stack/wrapping_paper, + /obj/item/stack/wrapping_paper) + cost = 10 + containername = "Arts and Crafts crate" + +///////////// Janitor Supplies + +/datum/supply_packs/misc/janitor + name = "Janitorial Supplies Crate" + contains = list(/obj/item/weapon/reagent_containers/glass/bucket, + /obj/item/weapon/reagent_containers/glass/bucket, + /obj/item/weapon/reagent_containers/glass/bucket, + /obj/item/weapon/mop, + /obj/item/weapon/caution, + /obj/item/weapon/caution, + /obj/item/weapon/caution, + /obj/item/weapon/storage/bag/trash, + /obj/item/weapon/reagent_containers/spray/cleaner, + /obj/item/weapon/reagent_containers/glass/rag, + /obj/item/weapon/grenade/chem_grenade/cleaner, + /obj/item/weapon/grenade/chem_grenade/cleaner, + /obj/item/weapon/grenade/chem_grenade/cleaner) + cost = 10 + containername = "janitorial supplies crate" + +/datum/supply_packs/misc/janitor/janicart + name = "Janitorial Cart and Galoshes Crate" + contains = list(/obj/structure/janitorialcart, + /obj/item/clothing/shoes/galoshes) + cost = 10 + containertype = /obj/structure/largecrate + containername = "janitorial cart crate" + +/datum/supply_packs/misc/janitor/janitank + name = "Janitor Watertank Backpack" + contains = list(/obj/item/weapon/watertank/janitor) + cost = 10 + containertype = /obj/structure/closet/crate/secure + containername = "janitor watertank crate" + access = access_janitor + +/datum/supply_packs/misc/janitor/lightbulbs + name = "Replacement Lights" + contains = list(/obj/item/weapon/storage/box/lights/mixed, + /obj/item/weapon/storage/box/lights/mixed, + /obj/item/weapon/storage/box/lights/mixed) + cost = 10 + containername = "replacement lights" + +///////////// Costumes + +/datum/supply_packs/misc/costume + name = "Standard Costume Crate" + contains = list(/obj/item/weapon/storage/backpack/clown, + /obj/item/clothing/shoes/clown_shoes, + /obj/item/clothing/mask/gas/clown_hat, + /obj/item/clothing/under/rank/clown, + /obj/item/weapon/bikehorn, + /obj/item/weapon/storage/backpack/mime, + /obj/item/clothing/under/mime, + /obj/item/clothing/shoes/black, + /obj/item/clothing/gloves/color/white, + /obj/item/clothing/mask/gas/mime, + /obj/item/clothing/head/beret, + /obj/item/clothing/suit/suspenders, + /obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing) + cost = 10 + containertype = /obj/structure/closet/crate/secure + containername = "standard costumes" + access = access_theatre + +/datum/supply_packs/misc/wizard + name = "Wizard Costume Crate" + contains = list(/obj/item/weapon/staff, + /obj/item/clothing/suit/wizrobe/fake, + /obj/item/clothing/shoes/sandal, + /obj/item/clothing/head/wizard/fake) + cost = 20 + containername = "wizard costume crate" + +/datum/supply_packs/misc/mafia + name = "Mafia Supply crate" + contains = list(/obj/item/clothing/suit/browntrenchcoat =1,/obj/item/clothing/suit/blacktrenchcoat =1,/obj/item/clothing/head/fedora/whitefedora =1, + /obj/item/clothing/head/fedora/brownfedora =1,/obj/item/clothing/head/fedora =1,/obj/item/clothing/under/flappers =1,/obj/item/clothing/under/mafia =1,/obj/item/clothing/under/mafia/vest =1,/obj/item/clothing/under/mafia/white =1, + /obj/item/clothing/under/mafia/sue =1,/obj/item/clothing/under/mafia/tan =1, /obj/item/toy/crossbow/tommygun =2) + cost = 15 + containername = "mafia supply crate" + +/datum/supply_packs/misc/randomised + var/num_contained = 3 //number of items picked to be contained in a randomised crate + contains = list(/obj/item/clothing/head/collectable/chef, + /obj/item/clothing/head/collectable/paper, + /obj/item/clothing/head/collectable/tophat, + /obj/item/clothing/head/collectable/captain, + /obj/item/clothing/head/collectable/beret, + /obj/item/clothing/head/collectable/welding, + /obj/item/clothing/head/collectable/flatcap, + /obj/item/clothing/head/collectable/pirate, + /obj/item/clothing/head/collectable/kitty, + /obj/item/clothing/head/collectable/rabbitears, + /obj/item/clothing/head/collectable/wizard, + /obj/item/clothing/head/collectable/hardhat, + /obj/item/clothing/head/collectable/HoS, + /obj/item/clothing/head/collectable/thunderdome, + /obj/item/clothing/head/collectable/swat, + /obj/item/clothing/head/collectable/slime, + /obj/item/clothing/head/collectable/police, + /obj/item/clothing/head/collectable/slime, + /obj/item/clothing/head/collectable/xenom, + /obj/item/clothing/head/collectable/petehat) + name = "Collectable hat crate!" + cost = 200 + containername = "collectable hats crate! Brought to you by Bass.inc!" + +/datum/supply_packs/misc/randomised/New() + manifest += "Contains any [num_contained] of:" + ..() + + +/datum/supply_packs/misc/randomised/contraband + num_contained = 5 + contains = list(/obj/item/weapon/storage/pill_bottle/zoom, + /obj/item/weapon/storage/pill_bottle/happy, + /obj/item/weapon/storage/pill_bottle/random_drug_bottle, + /obj/item/weapon/contraband/poster, + /obj/item/weapon/storage/fancy/cigarettes/dromedaryco, + /obj/item/weapon/storage/fancy/cigarettes/cigpack_shadyjims) + name = "Contraband Crate" + cost = 30 + containername = "crate" //let's keep it subtle, eh? + contraband = 1 + +/datum/supply_packs/misc/autodrobe + name = "Autodrobe Supply Crate" + contains = list(/obj/item/weapon/vending_refill/autodrobe, + /obj/item/weapon/vending_refill/autodrobe) + cost = 15 + containername = "autodrobe supply crate" + +/datum/supply_packs/misc/formalwear //This is a very classy crate. + name = "Formal-wear Crate" + contains = list(/obj/item/clothing/under/blacktango, + /obj/item/clothing/under/assistantformal, + /obj/item/clothing/under/assistantformal, + /obj/item/clothing/under/lawyer/bluesuit, + /obj/item/clothing/suit/storage/lawyer/bluejacket, + /obj/item/clothing/under/lawyer/purpsuit, + /obj/item/clothing/suit/storage/lawyer/purpjacket, + /obj/item/clothing/under/lawyer/black, + /obj/item/clothing/suit/storage/lawyer/blackjacket, + /obj/item/clothing/accessory/waistcoat, + /obj/item/clothing/accessory/blue, + /obj/item/clothing/accessory/red, + /obj/item/clothing/accessory/black, + /obj/item/clothing/head/bowlerhat, + /obj/item/clothing/head/fedora, + /obj/item/clothing/head/flatcap, + /obj/item/clothing/head/beret, + /obj/item/clothing/head/that, + /obj/item/clothing/shoes/laceup, + /obj/item/clothing/shoes/laceup, + /obj/item/clothing/shoes/laceup, + /obj/item/clothing/under/suit_jacket/charcoal, + /obj/item/clothing/under/suit_jacket/navy, + /obj/item/clothing/under/suit_jacket/burgundy, + /obj/item/clothing/under/suit_jacket/checkered, + /obj/item/clothing/under/suit_jacket/tan, + /obj/item/weapon/lipstick/random) + cost = 30 //Lots of very expensive items. You gotta pay up to look good! + containername = "formal-wear crate" diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index 8d864128905..1aae642647b 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -323,18 +323,18 @@ var/list/uplink_items = list() cost = 18 gamemodes = list("nuclear emergency") -/datum/uplink_item/ammo/bullstun - name = "Drum Magazine - 12g Stun Slug" - desc = "An additional 8-round stun slug magazine for use in the Bulldog shotgun. Saying that they're non-lethal would be lying." +/datum/uplink_item/ammo/bullbuck + name = "Drum Magazine - 12g buckshot" + desc = "An additional 8-round buckshot magazine for use in the Bulldog shotgun. Front towards enemy." item = /obj/item/ammo_box/magazine/m12g cost = 2 gamemodes = list("nuclear emergency") -/datum/uplink_item/ammo/bullbuck - name = "Drum Magazine - 12g Buckshot" - desc = "An alternative 8-round buckshot magazine for use in the Bulldog shotgun. Front towards enemy." - item = /obj/item/ammo_box/magazine/m12g/buckshot - cost = 2 +/datum/uplink_item/ammo/bullstun + name = "Drum Magazine - 12g Stun Slug" + desc = "An alternative 8-round stun slug magazine for use in the Bulldog shotgun. Saying that they're completely non-lethal would be lying." + item = /obj/item/ammo_box/magazine/m12g/stun + cost = 3 gamemodes = list("nuclear emergency") /datum/uplink_item/ammo/bulldragon @@ -371,10 +371,11 @@ var/list/uplink_items = list() /datum/uplink_item/stealthy_weapons category = "Stealthy and Inconspicuous Weapons" -/datum/uplink_item/stealthy_weapons/para_pen - name = "Paralysis Pen" - desc = "A syringe disguised as a functional pen, filled with a neuromuscular-blocking drug that renders a target mute on injection that will eventually cause them to pass out. The pen holds one dose of paralyzing agent,though it can be refilled." - item = /obj/item/weapon/pen/paralysis +/datum/uplink_item/stealthy_weapons/sleepy_pen + name = "Sleepy Pen" + desc = "A syringe disguised as a functional pen, filled with a potent mix of drugs, including a strong anaesthetic and a chemical that is capable of blocking the movement of the vocal chords. \ + The pen holds one dose of the mixture. The pen can be refilled." + item = /obj/item/weapon/pen/sleepy cost = 8 excludefrom = list("nuclear emergency") @@ -440,6 +441,12 @@ var/list/uplink_items = list() item = /obj/item/device/chameleon cost = 7 +/datum/uplink_item/stealthy_tools/camera_bug + name = "Camera Bug" + desc = "Enables you to bug cameras to view them remotely. Adding particular items to it alters its functions." + item = /obj/item/device/camera_bug + cost = 2 + /datum/uplink_item/stealthy_tools/dnascrambler name = "DNA Scrambler" desc = "A syringe with one injection that randomizes appearance and name upon use. A cheaper but less versatile alternative to an agent card and voice changer." @@ -480,7 +487,7 @@ var/list/uplink_items = list() /datum/uplink_item/device_tools/medkit - name = "Syndicate Medical Supply Kit" + name = "Syndicate Combat Medic Kit" desc = "The syndicate medkit is a suspicious black and red. Included is a combat stimulant injector for rapid healing, a medical hud for quick identification of injured comrades, \ and other medical supplies helpful for a medical field operative." item = /obj/item/weapon/storage/firstaid/tactical @@ -505,20 +512,6 @@ var/list/uplink_items = list() item = /obj/item/clothing/glasses/thermal/syndi cost = 6 -/* -/datum/uplink_item/device_tools/surveillance - name = "Camera Surveillance Kit" - desc = "This kit contains 5 Camera bugs and one mobile receiver. Attach camera bugs to a camera to enable remote viewing." - item = /obj/item/weapon/storage/box/syndie_kit/surveillance - cost = 5 - -/datum/uplink_item/device_tools/camerabugs - name = "Camera Bugs" - desc = "This is a Camera bug resupply giving you 5 more camera bugs." - item = /obj/item/weapon/storage/box/surveillance - cost = 4 -*/ //commented out until porting over TG's camera bug - /datum/uplink_item/device_tools/binary name = "Binary Translator Key" desc = "A key, that when inserted into a radio headset, allows you to listen to and talk with artificial intelligences and cybernetic organisms in binary." diff --git a/code/datums/visibility_networks/chunk.dm b/code/datums/visibility_networks/chunk.dm deleted file mode 100644 index 4abc1340b0f..00000000000 --- a/code/datums/visibility_networks/chunk.dm +++ /dev/null @@ -1,179 +0,0 @@ -#define UPDATE_BUFFER 25 // 2.5 seconds - -// CAMERA CHUNK -// -// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed. -// Allows the mob using this chunk to stream these chunks and know what it can and cannot see. - -/datum/visibility_chunk - var/obscured_image = 'icons/effects/cameravis.dmi' - var/obscured_sub = "black" - var/list/obscuredTurfs = list() - var/list/visibleTurfs = list() - var/list/obscured = list() - var/list/viewpoints = list() - var/list/turfs = list() - var/list/seenby = list() - var/visible = 0 - var/changed = 0 - var/updating = 0 - var/x = 0 - var/y = 0 - var/z = 0 - -/datum/visibility_chunk/proc/add(mob/new_mob) - - // if this thing doesn't use one of these visibility systems, kick it out - if (!new_mob.visibility_interface) - return - - // if the mob being added isn't a valid form of that mob, kick it out - if (!new_mob.visibility_interface:canBeAddedToChunk(src)) - return - - // add this chunk to the list of visible chunks - new_mob.visibility_interface:addChunk(src) - - visible++ - seenby += new_mob - if(changed && !updating) - update() - -/datum/visibility_chunk/proc/remove(mob/new_mob) - // if this thing doesn't use one of these visibility systems, kick it out - if (!new_mob.visibility_interface) - return - - // if the mob being added isn't a valid form of that mob, kick it out - if (!new_mob.visibility_interface:canBeAddedToChunk(src)) - return - - // remove the chunk - new_mob.visibility_interface:removeChunk(src) - - // remove the mob from out lists - seenby -= new_mob - if(visible > 0) - visible-- - -/datum/visibility_chunk/proc/visibilityChanged(turf/loc) - if(!visibleTurfs[loc]) - return - hasChanged() - -/datum/visibility_chunk/proc/hasChanged(var/update_now = 0) - if(visible || update_now) - if(!updating) - updating = 1 - spawn(UPDATE_BUFFER) // Batch large changes, such as many doors opening or closing at once - update() - updating = 0 - else - changed = 1 - - -/* -This function needs to be overwritten to return True if the viewpoint object is valid, and false if it is not. -*/ -/datum/visibility_chunk/proc/validViewpoint(var/viewpoint) - return FALSE - -/* -This function needs to be overwritten to return a list of visible turfs for that viewpoint -*/ -/datum/visibility_chunk/proc/getVisibleTurfsForViewpoint(var/viewpoint) - return list() - -// returns a list of turfs which can be seen in by the chunks viewpoints -/datum/visibility_chunk/proc/getVisibleTurfs() - var/list/newVisibleTurfs = list() - for(var/viewpoint in viewpoints) - if (validViewpoint(viewpoint)) - for (var/turf/t in getVisibleTurfsForViewpoint(viewpoint)) - newVisibleTurfs[t]=t - return newVisibleTurfs - -/* -This function needs to be overwritten to find nearby viewpoint objects to the chunk center. -*/ -/datum/visibility_chunk/proc/findNearbyViewpoints() - return FALSE - -/* -This function can be overwritten to change or randomize the obscuring images -*/ -/datum/visibility_chunk/proc/setObscuredImage(var/turf/target_turf) - if(!target_turf.obscured) - target_turf.obscured = image(obscured_image, target_turf, obscured_sub, 15) - -/datum/visibility_chunk/proc/update() - - set background = 1 - - // get a list of all the turfs that our viewpoints can see - var/list/newVisibleTurfs = getVisibleTurfs() - - // Removes turf that isn't in turfs. - newVisibleTurfs &= turfs - - var/list/visAdded = newVisibleTurfs - visibleTurfs - var/list/visRemoved = visibleTurfs - newVisibleTurfs - - visibleTurfs = newVisibleTurfs - obscuredTurfs = turfs - newVisibleTurfs - - // update the visibility overlays - for(var/turf in visAdded) - var/turf/t = turf - if(t.obscured) - obscured -= t.obscured - for(var/mob/current_mob in seenby) - if (current_mob.visibility_interface) - current_mob.visibility_interface:removeObscuredTurf(t) - - for(var/turf in visRemoved) - var/turf/t = turf - if(obscuredTurfs[t]) - setObscuredImage(t) - obscured += t.obscured - for(var/mob/current_mob in seenby) - if (current_mob.visibility_interface) - current_mob.visibility_interface:addObscuredTurf(t) - else - seenby -= current_mob - - -// Create a new chunk, since the chunks are made as they are needed. -/datum/visibility_chunk/New(loc, x, y, z) - - // 0xf = 15 - x &= ~0xf - y &= ~0xf - - src.x = x - src.y = y - src.z = z - - for(var/turf/t in range(10, locate(x + 8, y + 8, z))) - if(t.x >= x && t.y >= y && t.x < x + 16 && t.y < y + 16) - turfs[t] = t - - // locate all nearby viewpoints - findNearbyViewpoints() - - // get the turfs that are visible to those viewpoints - visibleTurfs = getVisibleTurfs() - - // Removes turf that isn't in turfs. - visibleTurfs &= turfs - - // create the list of turfs we can't see - obscuredTurfs = turfs - visibleTurfs - - // create the list of obscuring images to add to viewing clients - for(var/turf in obscuredTurfs) - var/turf/t = turf - setObscuredImage(t) - obscured += t.obscured - -#undef UPDATE_BUFFER \ No newline at end of file diff --git a/code/datums/visibility_networks/dictionary.dm b/code/datums/visibility_networks/dictionary.dm deleted file mode 100644 index 5f57ddd7a17..00000000000 --- a/code/datums/visibility_networks/dictionary.dm +++ /dev/null @@ -1,11 +0,0 @@ -var/datum/visibility_network/cameras/cameranet = new() -var/datum/visibility_network/cult/cultNetwork = new() -var/datum/visibility_network/list/visibility_networks = list("ALL_CAMERAS"=cameranet, "CULT" = cultNetwork) - - -// used by turfs and objects to update all visibility networks -/proc/updateVisibilityNetworks(atom/A, var/opacity_check = 1) - var/datum/visibility_network/currentNetwork - for (var/networkName in visibility_networks) - currentNetwork = visibility_networks[networkName] - currentNetwork.updateVisibility(A, opacity_check) \ No newline at end of file diff --git a/code/datums/visibility_networks/update_triggers.dm b/code/datums/visibility_networks/update_triggers.dm deleted file mode 100644 index 97ed2db3a6c..00000000000 --- a/code/datums/visibility_networks/update_triggers.dm +++ /dev/null @@ -1,94 +0,0 @@ -//UPDATE TRIGGERS, when the chunk (and the surrounding chunks) should update. - -// TURFS - -/turf - var/image/obscured - -/turf/proc/visibilityChanged() - if(ticker) - updateVisibilityNetworks(src) - -/turf/simulated/Del() - visibilityChanged() - ..() - -/turf/simulated/New() - ..() - visibilityChanged() - - - -// STRUCTURES - -/obj/structure/Del() - if(ticker) - updateVisibilityNetworks(src) - ..() - -/obj/structure/New() - ..() - if(ticker) - updateVisibilityNetworks(src) - -// EFFECTS - -/obj/effect/Del() - if(ticker) - updateVisibilityNetworks(src) - ..() - -/obj/effect/New() - ..() - if(ticker) - updateVisibilityNetworks(src) - - -// DOORS - -// Simply updates the visibility of the area when it opens/closes/destroyed. -/obj/machinery/door/proc/update_nearby_tiles(need_rebuild) - - if(!glass) - updateVisibilityNetworks(src,0) - - if(!air_master) - return 0 - - for(var/turf/simulated/turf in locs) - update_heat_protection(turf) - air_master.mark_for_update(turf) - - return 1 - - - -#define UPDATE_VISIBILITY_NETWORK_BUFFER 30 - -/mob - var/datum/visibility_network/list/visibilityNetworks=list() - var/updatingVisibilityNetworks=FALSE - -/mob/Move(n,direct) - var/oldLoc = src.loc - //. = ..() - if(..(n,direct)) - if(src.visibilityNetworks.len) - if(!src.updatingVisibilityNetworks) - src.updatingVisibilityNetworks = 1 - spawn(UPDATE_VISIBILITY_NETWORK_BUFFER) - if(oldLoc != src.loc) - for (var/datum/visibility_network/currentNetwork in src.visibilityNetworks) - currentNetwork.updateMob(src) - src.updatingVisibilityNetworks = 0 - return . - -/mob/proc/addToVisibilityNetwork(var/datum/visibility_network/network) - if(network) - src.visibilityNetworks+=network - -/mob/proc/removeFromVisibilityNetwork(var/datum/visibility_network/network) - if(network) - src.visibilityNetworks|=network - -#undef UPDATE_VISIBILITY_NETWORK_BUFFER \ No newline at end of file diff --git a/code/datums/visibility_networks/visibility_interface.dm b/code/datums/visibility_networks/visibility_interface.dm deleted file mode 100644 index 7d8efba41d3..00000000000 --- a/code/datums/visibility_networks/visibility_interface.dm +++ /dev/null @@ -1,46 +0,0 @@ -/datum/visibility_interface - var/chunk_type = null - var/mob/controller = null - var/list/visible_chunks = list() - - -/datum/visibility_interface/New(var/mob/controller) - src.controller = controller - - -/datum/visibility_interface/proc/validMob() - return getClient() - -/datum/visibility_interface/proc/getClient() - return controller.client - -/datum/visibility_interface/proc/canBeAddedToChunk(var/datum/visibility_chunk/test_chunk) - return istype(test_chunk,chunk_type) - - -/datum/visibility_interface/proc/addChunk(var/datum/visibility_chunk/test_chunk) - visible_chunks+=test_chunk - var/client/currentClient = getClient() - if(currentClient) - currentClient.images += test_chunk.obscured - - -/datum/visibility_interface/proc/removeChunk(var/datum/visibility_chunk/test_chunk) - visible_chunks-=test_chunk - var/client/currentClient = getClient() - if(currentClient) - currentClient.images -= test_chunk.obscured - - -/datum/visibility_interface/proc/removeObscuredTurf(var/turf/target_turf) - if(validMob()) - var/client/currentClient = getClient() - if(currentClient) - currentClient.images -= target_turf.obscured - - -/datum/visibility_interface/proc/addObscuredTurf(var/turf/target_turf) - if(validMob()) - var/client/currentClient = getClient() - if(currentClient) - currentClient.images -= target_turf.obscured \ No newline at end of file diff --git a/code/datums/visibility_networks/visibility_network.dm b/code/datums/visibility_networks/visibility_network.dm deleted file mode 100644 index f1bc24e771a..00000000000 --- a/code/datums/visibility_networks/visibility_network.dm +++ /dev/null @@ -1,144 +0,0 @@ -/datum/visibility_network - var/list/viewpoints = list() - - // the type of chunk used by this network - var/datum/visibility_chunk/ChunkType = /datum/visibility_chunk - - // The chunks of the map, mapping the areas that the viewpoints can see. - var/list/chunks = list() - - var/ready = 0 - - -// Creates a chunk key string from x,y,z coordinates -/datum/visibility_network/proc/createChunkKey(x,y,z) - x &= ~0xf - y &= ~0xf - return "[x],[y],[z]" - - -// Checks if a chunk has been Generated in x, y, z. -/datum/visibility_network/proc/chunkGenerated(x, y, z) - return (chunks[createChunkKey(x, y, z)]) - - -// Returns the chunk in the x, y, z. -// If there is no chunk, it creates a new chunk and returns that. -/datum/visibility_network/proc/getChunk(x, y, z) - var/key = createChunkKey(x, y, z) - if(!chunks[key]) - chunks[key] = new ChunkType(null, x, y, z) - return chunks[key] - - -/datum/visibility_network/proc/visibility(var/mob/targetMob) - - // if we've got not visibility interface on the mob, we canot do this - if (!targetMob.visibility_interface) - return - - // 0xf = 15 - var/x1 = max(0, targetMob.x - 16) & ~0xf - var/y1 = max(0, targetMob.y - 16) & ~0xf - var/x2 = min(world.maxx, targetMob.x + 16) & ~0xf - var/y2 = min(world.maxy, targetMob.y + 16) & ~0xf - - var/list/visibleChunks = list() - - for(var/x = x1; x <= x2; x += 16) - for(var/y = y1; y <= y2; y += 16) - visibleChunks += getChunk(x, y, targetMob.z) - - var/list/remove = targetMob.visibility_interface:visible_chunks - visibleChunks - var/list/add = visibleChunks - targetMob.visibility_interface:visible_chunks - - for(var/datum/visibility_chunk/chunk in remove) - chunk.remove(targetMob) - - for(var/datum/visibility_chunk/chunk in add) - chunk.add(targetMob) - - -// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. -/datum/visibility_network/proc/updateVisibility(atom/A, var/opacity_check = 1) - if(!ticker || (opacity_check && !A.opacity)) - return - majorChunkChange(A, 2) - - -/datum/visibility_network/proc/updateChunk(x, y, z) - if(!chunkGenerated(x, y, z)) - return - var/datum/visibility_chunk/chunk = getChunk(x, y, z) - chunk.hasChanged() - - -/datum/visibility_network/proc/validViewpoint(var/viewpoint) - return FALSE - - -/datum/visibility_network/proc/addViewpoint(var/viewpoint) - if(validViewpoint(viewpoint)) - majorChunkChange(viewpoint, 1) - - -/datum/visibility_network/proc/removeViewpoint(var/viewpoint) - if(validViewpoint(viewpoint)) - majorChunkChange(viewpoint, 0) - -/datum/visibility_network/proc/getViewpointFromMob(var/mob/currentMob) - return FALSE - -/datum/visibility_network/proc/updateMob(var/mob/currentMob) - var/viewpoint = getViewpointFromMob(currentMob) - if(viewpoint) - updateViewpoint(viewpoint) - - -/datum/visibility_network/proc/updateViewpoint(var/viewpoint) - if(validViewpoint(viewpoint)) - majorChunkChange(viewpoint, 1) - - -// Never access this proc directly!!!! -// This will update the chunk and all the surrounding chunks. -// It will also add the atom to the cameras list if you set the choice to 1. -// Setting the choice to 0 will remove the viewpoint from the chunks. -// If you want to update the chunks around an object, without adding/removing a viewpoint, use choice 2. -/datum/visibility_network/proc/majorChunkChange(atom/c, var/choice) - // 0xf = 15 - if(!c) - return - - var/turf/T = get_turf(c) - if(T) - var/x1 = max(0, T.x - 8) & ~0xf - var/y1 = max(0, T.y - 8) & ~0xf - var/x2 = min(world.maxx, T.x + 8) & ~0xf - var/y2 = min(world.maxy, T.y + 8) & ~0xf - - for(var/x = x1; x <= x2; x += 16) - for(var/y = y1; y <= y2; y += 16) - if(chunkGenerated(x, y, T.z)) - var/datum/visibility_chunk/chunk = getChunk(x, y, T.z) - if(choice == 0) - // Remove the viewpoint. - chunk.viewpoints -= c - else if(choice == 1) - // You can't have the same viewpoint in the list twice. - chunk.viewpoints |= c - chunk.hasChanged() - -// checks if the network can see a particular atom -/datum/visibility_network/proc/checkCanSee(var/atom/target) - var/turf/position = get_turf(target) - return checkTurfVis(position) - -/datum/visibility_network/proc/checkTurfVis(var/turf/position) - var/datum/visibility_chunk/chunk = getChunk(position.x, position.y, position.z) - if(chunk) - if(chunk.changed) - chunk.hasChanged(1) // Update now, no matter if it's visible or not. - if(chunk.visibleTurfs[position]) - return 1 - return 0 \ No newline at end of file diff --git a/code/datums/wires/airlock.dm b/code/datums/wires/airlock.dm index 3b6d009a5ff..211e82d4394 100644 --- a/code/datums/wires/airlock.dm +++ b/code/datums/wires/airlock.dm @@ -33,14 +33,16 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048 /datum/wires/airlock/GetInteractWindow() var/obj/machinery/door/airlock/A = holder + var/haspower = A.arePowerSystemsOn() . += ..() - . += text("
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]", (A.locked ? "The door bolts have fallen!" : "The door bolts look up."), - (A.lights ? "The door bolt lights are on." : "The door bolt lights are off!"), - ((A.arePowerSystemsOn() && !(A.stat & NOPOWER)) ? "The test light is on." : "The test light is off!"), - (A.aiControlDisabled==0 ? "The 'AI control allowed' light is on." : "The 'AI control allowed' light is off."), - (A.safe==0 ? "The 'Check Wiring' light is on." : "The 'Check Wiring' light is off."), - (A.normalspeed==0 ? "The 'Check Timing Mechanism' light is on." : "The 'Check Timing Mechanism' light is off."), - (A.emergency==0 ? "The emergency lights are off." : "The emergency lights are on.")) + . += text("
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]", + (A.locked ? "The door bolts have fallen!" : "The door bolts look up."), + ((A.lights && haspower) ? "The door bolt lights are on." : "The door bolt lights are off!"), + ((haspower) ? "The test light is on." : "The test light is off!"), + ((A.aiControlDisabled==0 && !A.emagged && haspower) ? "The 'AI control allowed' light is on." : "The 'AI control allowed' light is off."), + ((A.safe==0 && haspower) ? "The 'Check Wiring' light is on." : "The 'Check Wiring' light is off."), + ((A.normalspeed==0 && haspower) ? "The 'Check Timing Mechanism' light is on." : "The 'Check Timing Mechanism' light is off."), + ((A.emergency==0 && haspower) ? "The emergency lights are off." : "The emergency lights are on.")) /datum/wires/airlock/UpdateCut(var/index, var/mended) @@ -125,7 +127,7 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048 switch(index) if(AIRLOCK_WIRE_IDSCAN) //Sending a pulse through this disables emergency access and flashes the red light on the door (if the door has power). - if((A.arePowerSystemsOn()) && (!(A.stat & NOPOWER))) + if((A.arePowerSystemsOn()) && A.density) A.door_animate("deny") if(A.emergency) A.emergency = 0 diff --git a/code/datums/wires/radio.dm b/code/datums/wires/radio.dm index a8171270008..9da8890ac32 100644 --- a/code/datums/wires/radio.dm +++ b/code/datums/wires/radio.dm @@ -21,11 +21,24 @@ var/const/WIRE_TRANSMIT = 4 var/obj/item/device/radio/R = holder switch(index) if(WIRE_SIGNAL) - R.listening = !R.listening - R.broadcasting = R.listening + R.listening = !R.listening && !IsIndexCut(WIRE_RECEIVE) + R.broadcasting = R.listening && !IsIndexCut(WIRE_TRANSMIT) if(WIRE_RECEIVE) - R.listening = !R.listening + R.listening = !R.listening && !IsIndexCut(WIRE_SIGNAL) if(WIRE_TRANSMIT) - R.broadcasting = !R.broadcasting \ No newline at end of file + R.broadcasting = !R.broadcasting && !IsIndexCut(WIRE_SIGNAL) + +/datum/wires/radio/UpdateCut(var/index, var/mended) + var/obj/item/device/radio/R = holder + switch(index) + if(WIRE_SIGNAL) + R.listening = mended && !IsIndexCut(WIRE_RECEIVE) + R.broadcasting = mended && !IsIndexCut(WIRE_TRANSMIT) + + if(WIRE_RECEIVE) + R.listening = mended && !IsIndexCut(WIRE_SIGNAL) + + if(WIRE_TRANSMIT) + R.broadcasting = mended && !IsIndexCut(WIRE_SIGNAL) diff --git a/code/datums/wires/vending.dm b/code/datums/wires/vending.dm index c0c76cd89ae..574c7961e09 100644 --- a/code/datums/wires/vending.dm +++ b/code/datums/wires/vending.dm @@ -1,3 +1,5 @@ +#define CAT_HIDDEN 2 // Also in code/game/machinery/vending.dm + /datum/wires/vending holder_type = /obj/machinery/vending wire_count = 4 @@ -17,17 +19,12 @@ var/const/VENDING_WIRE_IDSCAN = 8 return 1 return 0 -/datum/wires/vending/Interact(var/mob/living/user) - if(CanUse(user)) - var/obj/machinery/vending/V = holder - V.attack_hand(user) - /datum/wires/vending/GetInteractWindow() var/obj/machinery/vending/V = holder . += ..() . += "
The orange light is [V.seconds_electrified ? "on" : "off"].
" . += "The red light is [V.shoot_inventory ? "off" : "blinking"].
" - . += "The green light is [V.extended_inventory ? "on" : "off"].
" + . += "The green light is [(V.categories & CAT_HIDDEN) ? "on" : "off"].
" . += "A [V.scan_id ? "purple" : "yellow"] light is on.
" /datum/wires/vending/UpdatePulsed(var/index) @@ -36,7 +33,7 @@ var/const/VENDING_WIRE_IDSCAN = 8 if(VENDING_WIRE_THROW) V.shoot_inventory = !V.shoot_inventory if(VENDING_WIRE_CONTRABAND) - V.extended_inventory = !V.extended_inventory + V.categories ^= CAT_HIDDEN if(VENDING_WIRE_ELECTRIFY) V.seconds_electrified = 30 if(VENDING_WIRE_IDSCAN) @@ -48,7 +45,7 @@ var/const/VENDING_WIRE_IDSCAN = 8 if(VENDING_WIRE_THROW) V.shoot_inventory = !mended if(VENDING_WIRE_CONTRABAND) - V.extended_inventory = 0 + V.categories &= ~CAT_HIDDEN if(VENDING_WIRE_ELECTRIFY) if(mended) V.seconds_electrified = 0 diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm index c3d07013d14..04c3541dc7e 100644 --- a/code/datums/wires/wires.dm +++ b/code/datums/wires/wires.dm @@ -72,8 +72,11 @@ var/list/wireColours = list("red", "blue", "green", "black", "orange", "brown", html = GetInteractWindow() if(html) user.set_machine(holder) - //user << browse(html, "window=wires;size=[window_x]x[window_y]") - //onclose(user, "wires") + else + user.unset_machine() + // No content means no window. + user << browse(null, "window=wires") + return var/datum/browser/popup = new(user, "wires", holder.name, window_x, window_y) popup.set_content(html) popup.set_title_image(user.browse_rsc_icon(holder.icon, holder.icon_state)) diff --git a/code/defines/obj.dm b/code/defines/obj.dm index aff00b487eb..5eb6c3b54fc 100644 --- a/code/defines/obj.dm +++ b/code/defines/obj.dm @@ -4,7 +4,7 @@ anchored = 1 density = 1 - attackby(obj/item/weapon/W as obj, mob/user as mob) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) return attack_hand(user) attack_hand(mob/user as mob) @@ -19,7 +19,7 @@ anchored = 1 density = 0 - attackby(obj/item/weapon/W as obj, mob/user as mob) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) return attack_hand(user) @@ -380,7 +380,7 @@ var/global/list/PDA_Manifest = list() throwforce = 0.0 throw_speed = 1 throw_range = 20 - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT /obj/effect/stop diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index e8fba96a0d0..c00ba0f9061 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -3,7 +3,7 @@ desc = "Should anything ever go wrong..." icon = 'icons/obj/items.dmi' icon_state = "red_phone" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT force = 3.0 throwforce = 2.0 throw_speed = 1 @@ -22,7 +22,6 @@ anchored = 0.0 var/matter = 0 var/mode = 1 - flags = TABLEPASS w_class = 3.0 /obj/item/weapon/bananapeel @@ -108,7 +107,7 @@ icon = 'icons/obj/weapons.dmi' icon_state = "cane" item_state = "stick" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT force = 5.0 throwforce = 7.0 w_class = 2.0 @@ -160,7 +159,7 @@ gender = PLURAL icon = 'icons/obj/items.dmi' icon_state = "handcuff" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT throwforce = 0 w_class = 3.0 origin_tech = "materials=1" @@ -235,7 +234,7 @@ if(H) user << "You use [src] to destroy [H]." signs -= H - del(H) + qdel(H) else if(signs.len < max_signs) H = new(get_turf(target)) @@ -251,7 +250,7 @@ if(signs.len) var/list/L = signs.Copy() for(var/sign in L) - del(sign) + qdel(sign) signs -= sign user << "You clear all active holograms." @@ -272,7 +271,6 @@ throw_speed = 1 throw_range = 5 w_class = 2.0 - flags = FPRINT | TABLEPASS attack_verb = list("warned", "cautioned", "smashed") proximity_sign @@ -315,7 +313,7 @@ if(ishuman(C)) dead_legs(C) if(src) - del(src) + qdel(src) proc/dead_legs(mob/living/carbon/human/H as mob) var/datum/organ/external/l = H.get_organ("l_leg") @@ -335,7 +333,7 @@ desc = "Parts of a rack." icon = 'icons/obj/items.dmi' icon_state = "rack_parts" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT m_amt = 3750 /*/obj/item/weapon/syndicate_uplink @@ -349,7 +347,7 @@ var/traitor_frequency = 0.0 var/mob/currentUser = null var/obj/item/device/radio/origradio = null - flags = FPRINT | TABLEPASS | CONDUCT | ONBELT + flags = CONDUCT | ONBELT w_class = 2.0 item_state = "radio" throw_speed = 4 @@ -367,7 +365,7 @@ var/selfdestruct = 0.0 var/traitor_frequency = 0.0 var/obj/item/device/radio/origradio = null - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT item_state = "radio" throwforce = 5 @@ -387,7 +385,7 @@ throw_speed = 1 throw_range = 5 w_class = 2.0 - flags = FPRINT | TABLEPASS | NOSHIELD + flags = NOSHIELD attack_verb = list("bludgeoned", "whacked", "disciplined") /obj/item/weapon/staff/broom @@ -407,7 +405,7 @@ throw_speed = 1 throw_range = 5 w_class = 2.0 - flags = FPRINT | TABLEPASS | NOSHIELD + flags = NOSHIELD /obj/item/weapon/table_parts name = "table parts" @@ -416,7 +414,7 @@ icon = 'icons/obj/items.dmi' icon_state = "table_parts" m_amt = 3750 - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT attack_verb = list("slammed", "bashed", "battered", "bludgeoned", "thrashed", "whacked") /obj/item/weapon/table_parts/reinforced @@ -425,7 +423,7 @@ icon = 'icons/obj/items.dmi' icon_state = "reinf_tableparts" m_amt = 7500 - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT /obj/item/weapon/table_parts/wood name = "wooden table parts" @@ -453,7 +451,7 @@ icon_state = "std_module" w_class = 2.0 item_state = "electronic" - flags = FPRINT|TABLEPASS|CONDUCT + flags = CONDUCT var/mtype = 1 // 1=electronic 2=hardware /obj/item/weapon/module/card_reader @@ -481,48 +479,12 @@ icon_state = "power_mod" desc = "Charging circuits for power cells." - -/obj/item/device/camera_bug - name = "camera bug" - desc = "Tiny electronic device meant to bug cameras for viewing later." - icon = 'icons/obj/device.dmi' - icon_state = "implant_evil" - w_class = 1.0 - item_state = "" - throw_speed = 4 - throw_range = 20 - -/obj/item/weapon/camera_bug/attack_self(mob/usr as mob) - var/list/cameras = new/list() - for (var/obj/machinery/camera/C in cameranet.viewpoints) - if (C.bugged && C.status) - cameras.Add(C) - if (length(cameras) == 0) - usr << "\red No bugged functioning cameras found." - return - - var/list/friendly_cameras = new/list() - - for (var/obj/machinery/camera/C in cameras) - friendly_cameras.Add(C.c_tag) - - var/target = input("Select the camera to observe", null) as null|anything in friendly_cameras - if (!target) - return - for (var/obj/machinery/camera/C in cameras) - if (C.c_tag == target) - target = C - break - if (usr.stat == 2) return - - usr.client.eye = target - /obj/item/weapon/hatchet name = "hatchet" desc = "A very sharp axe blade upon a short fibremetal handle. It has a long history of chopping things, but now it is used for chopping wood." icon = 'icons/obj/weapons.dmi' icon_state = "hatchet" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT force = 12.0 sharp = 1 edge = 1 @@ -553,7 +515,7 @@ throw_speed = 2 throw_range = 3 w_class = 4.0 - flags = FPRINT | TABLEPASS | NOSHIELD + flags = NOSHIELD slot_flags = SLOT_BACK origin_tech = "materials=2;combat=2" attack_verb = list("chopped", "sliced", "cut", "reaped") @@ -564,8 +526,8 @@ if(istype(A, /obj/effect/plantsegment)) for(var/obj/effect/plantsegment/B in orange(A,1)) if(prob(80)) - del B - del A + qdel(B) + qdel(A) /* /obj/item/weapon/cigarpacket @@ -577,7 +539,7 @@ w_class = 1 throwforce = 2 var/cigarcount = 6 - flags = ONBELT | TABLEPASS */ + flags = ONBELT */ /obj/item/weapon/pai_cable desc = "A flexible coated cable with a universal jack on one end." @@ -596,7 +558,7 @@ item_state = "RPED" icon_override = 'icons/mob/in-hand/tools.dmi' w_class = 5 - can_hold = list("/obj/item/weapon/stock_parts","/obj/item/weapon/cell") + can_hold = list("/obj/item/weapon/stock_parts") storage_slots = 50 use_to_pickup = 1 allow_quick_gather = 1 @@ -672,6 +634,7 @@ /obj/item/weapon/stock_parts/capacitor/adv name = "advanced capacitor" desc = "An advanced capacitor used in the construction of a variety of devices." + icon_state = "adv_capacitor" origin_tech = "powerstorage=3" rating = 2 m_amt = 50 @@ -680,7 +643,7 @@ /obj/item/weapon/stock_parts/scanning_module/adv name = "advanced scanning module" desc = "A compact, high resolution scanning module used in the construction of certain devices." - icon_state = "scan_module" + icon_state = "adv_scan_module" origin_tech = "magnets=3" rating = 2 m_amt = 50 @@ -716,6 +679,7 @@ /obj/item/weapon/stock_parts/capacitor/super name = "super capacitor" desc = "A super-high capacity capacitor used in the construction of a variety of devices." + icon_state = "super_capacitor" origin_tech = "powerstorage=5;materials=4" rating = 3 m_amt = 50 @@ -724,6 +688,7 @@ /obj/item/weapon/stock_parts/scanning_module/phasic name = "phasic scanning module" desc = "A compact, high resolution phasic scanning module used in the construction of certain devices." + icon_state = "super_scan_module" origin_tech = "magnets=5" rating = 3 m_amt = 50 @@ -832,7 +797,6 @@ icon = 'icons/obj/lightning.dmi' icon_state = "lightning" desc = "test lightning" - flags = USEDELAY New() icon = midicon diff --git a/code/defines/procs/announce.dm b/code/defines/procs/announce.dm new file mode 100644 index 00000000000..7cb7799a372 --- /dev/null +++ b/code/defines/procs/announce.dm @@ -0,0 +1,121 @@ +/var/datum/announcement/priority/priority_announcement = new(do_log = 0) +/var/datum/announcement/priority/command/command_announcement = new(do_log = 0, do_newscast = 1) + +/datum/announcement + var/title = "Attention" + var/announcer = "" + var/log = 0 + var/sound + var/newscast = 0 + var/channel_name = "Station Announcements" + var/announcement_type = "Announcement" + var/disable_newscasts = 1 // Bay also adds announcements to their newscaster system - set this to 0 to also use that system + +/datum/announcement/New(var/do_log = 0, var/new_sound = null, var/do_newscast = 0) + sound = new_sound + log = do_log + newscast = do_newscast + +/datum/announcement/priority/New(var/do_log = 1, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0) + ..(do_log, new_sound, do_newscast) + title = "Priority Announcement" + announcement_type = "Priority Announcement" + +/datum/announcement/priority/command/New(var/do_log = 1, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0) + ..(do_log, new_sound, do_newscast) + title = "[command_name()] Update" + announcement_type = "[command_name()] Update" + +/datum/announcement/priority/security/New(var/do_log = 1, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0) + ..(do_log, new_sound, do_newscast) + title = "Security Announcement" + announcement_type = "Security Announcement" + +/datum/announcement/proc/Announce(var/message as text, var/new_title = "", var/new_sound = null, var/do_newscast = newscast) + if(!message) + return + var/tmp/message_title = new_title ? new_title : title + var/tmp/message_sound = new_sound ? sound(new_sound) : sound + + message = trim_strip_html_properly(message) + message_title = html_encode(message_title) + + Message(message, message_title) + if(do_newscast) + NewsCast(message, message_title) + Sound(message_sound) + Log(message, message_title) + +datum/announcement/proc/Message(message as text, message_title as text) + for(var/mob/M in player_list) + if(!istype(M,/mob/new_player) && !isdeaf(M)) + M << "

[title]

" + M << "[message]" + if (announcer) + M << " -[html_encode(announcer)]" + +datum/announcement/minor/Message(message as text, message_title as text) + world << "[message]" + +datum/announcement/priority/Message(message as text, message_title as text) + world << "

[message_title]

" + world << "[message]" + if(announcer) + world << " -[html_encode(announcer)]" + world << "
" + +datum/announcement/priority/command/Message(message as text, message_title as text) + var/command + command += "

[command_name()] Update

" + if (message_title) + command += "

[message_title]

" + + command += "
[message]
" + command += "
" + for(var/mob/M in player_list) + if(!istype(M,/mob/new_player) && !isdeaf(M)) + M << command + +datum/announcement/priority/security/Message(message as text, message_title as text) + world << "[message_title]" + world << "[message]" + +datum/announcement/proc/NewsCast(message as text, message_title as text) + if(disable_newscasts) + return + if(!newscast) + return + + var/datum/news_announcement/news = new + news.channel_name = channel_name + news.author = announcer + news.message = message + news.message_type = announcement_type + news.can_be_redacted = 0 + announce_newscaster_news(news) + +datum/announcement/proc/PlaySound(var/message_sound) + if(!message_sound) + return + for(var/mob/M in player_list) + if(!istype(M,/mob/new_player) && !isdeaf(M)) + M << message_sound + +datum/announcement/proc/Sound(var/message_sound) + PlaySound(message_sound) + +datum/announcement/priority/Sound(var/message_sound) + if(sound) + world << sound + +datum/announcement/priority/command/Sound(var/message_sound) + PlaySound(message_sound) + +datum/announcement/proc/Log(message as text, message_title as text) + if(log) + log_say("[key_name(usr)] has made \a [announcement_type]: [message_title] - [message] - [announcer]") + message_admins("[key_name_admin(usr)] has made \a [announcement_type].", 1) + +/proc/GetNameAndAssignmentFromId(var/obj/item/weapon/card/id/I) + // Format currently matches that of newscaster feeds: Registered Name (Assigned Rank) + return I.assignment ? "[I.registered_name] ([I.assignment])" : I.registered_name diff --git a/code/defines/procs/captain_announce.dm b/code/defines/procs/captain_announce.dm deleted file mode 100644 index 9b91705ea56..00000000000 --- a/code/defines/procs/captain_announce.dm +++ /dev/null @@ -1,5 +0,0 @@ -/proc/captain_announce(var/text) - world << "

Priority Announcement

" - world << "[html_encode(text)]" - world << "
" - diff --git a/code/defines/procs/command_alert.dm b/code/defines/procs/command_alert.dm deleted file mode 100644 index 6545307fa1a..00000000000 --- a/code/defines/procs/command_alert.dm +++ /dev/null @@ -1,11 +0,0 @@ -/proc/command_alert(var/text, var/title = "") - var/command - command += "

[command_name()] Update

" - if (title && length(title) > 0) - command += "

[html_encode(title)]

" - - command += "
[html_encode(text)]
" - command += "
" - for(var/mob/M in player_list) - if(!istype(M,/mob/new_player)) - M << command diff --git a/code/defines/procs/radio.dm b/code/defines/procs/radio.dm new file mode 100644 index 00000000000..1e0e045928b --- /dev/null +++ b/code/defines/procs/radio.dm @@ -0,0 +1,81 @@ +#define TELECOMMS_RECEPTION_NONE 0 +#define TELECOMMS_RECEPTION_SENDER 1 +#define TELECOMMS_RECEPTION_RECEIVER 2 +#define TELECOMMS_RECEPTION_BOTH 3 + +/proc/get_frequency_name(var/display_freq) + var/freq_text + + // the name of the channel + if(display_freq in ANTAG_FREQS) + freq_text = "#unkn" + else + for(var/channel in radiochannels) + if(radiochannels[channel] == display_freq) + freq_text = channel + break + + // --- If the frequency has not been assigned a name, just use the frequency as the name --- + if(!freq_text) + freq_text = format_frequency(display_freq) + + return freq_text + +/datum/reception + var/obj/machinery/message_server/message_server = null + var/telecomms_reception = TELECOMMS_RECEPTION_NONE + var/message = "" + +/datum/receptions + var/obj/machinery/message_server/message_server = null + var/sender_reception = TELECOMMS_RECEPTION_NONE + var/list/receiver_reception = new + +/proc/get_message_server() + if(message_servers) + for (var/obj/machinery/message_server/MS in message_servers) + if(MS.active) + return MS + return null + +/proc/check_signal(var/datum/signal/signal) + return signal && signal.data["done"] + +/proc/get_sender_reception(var/atom/sender, var/datum/signal/signal) + return check_signal(signal) ? TELECOMMS_RECEPTION_SENDER : TELECOMMS_RECEPTION_NONE + +/proc/get_receiver_reception(var/receiver, var/datum/signal/signal) + if(receiver && check_signal(signal)) + var/turf/pos = get_turf(receiver) + if(pos && (pos.z in signal.data["level"])) + return TELECOMMS_RECEPTION_RECEIVER + return TELECOMMS_RECEPTION_NONE + +/proc/get_reception(var/atom/sender, var/receiver, var/message = "", var/do_sleep = 1) + var/datum/reception/reception = new + + // check if telecomms I/O route 1459 is stable + reception.message_server = get_message_server() + + var/datum/signal/signal = sender.telecomms_process(do_sleep) // Be aware that this proc calls sleep, to simulate transmition delays + reception.telecomms_reception |= get_sender_reception(sender, signal) + reception.telecomms_reception |= get_receiver_reception(receiver, signal) + reception.message = signal && signal.data["compression"] > 0 ? Gibberish(message, signal.data["compression"] + 50) : message + + return reception + +/proc/get_receptions(var/atom/sender, var/list/atom/receivers, var/do_sleep = 1) + var/datum/receptions/receptions = new + receptions.message_server = get_message_server() + + var/datum/signal/signal + if(sender) + signal = sender.telecomms_process(do_sleep) + receptions.sender_reception = get_sender_reception(sender, signal) + + for(var/atom/receiver in receivers) + if(!signal) + signal = receiver.telecomms_process() + receptions.receiver_reception[receiver] = get_receiver_reception(receiver, signal) + + return receptions diff --git a/code/defines/procs/records.dm b/code/defines/procs/records.dm new file mode 100644 index 00000000000..4e9fbcc9afc --- /dev/null +++ b/code/defines/procs/records.dm @@ -0,0 +1,48 @@ +/proc/CreateGeneralRecord() + var/mob/living/carbon/human/dummy = new() + dummy.mind = new() + var/icon/front = new(get_id_photo(dummy), dir = SOUTH) + var/icon/side = new(get_id_photo(dummy), dir = WEST) + var/datum/data/record/G = new /datum/data/record() + G.fields["name"] = "New Record" + G.fields["id"] = text("[]", add_zero(num2hex(rand(1, 1.6777215E7)), 6)) + G.fields["rank"] = "Unassigned" + G.fields["real_rank"] = "Unassigned" + G.fields["sex"] = "Male" + G.fields["age"] = "Unknown" + G.fields["fingerprint"] = "Unknown" + G.fields["p_stat"] = "Active" + G.fields["m_stat"] = "Stable" + G.fields["species"] = "Human" + G.fields["home_system"] = "Unknown" + G.fields["citizenship"] = "Unknown" + G.fields["faction"] = "Unknown" + G.fields["religion"] = "Unknown" + G.fields["photo_front"] = front + G.fields["photo_side"] = side + data_core.general += G + + del(dummy) + return G + +/proc/CreateSecurityRecord(var/name as text, var/id as text) + var/datum/data/record/R = new /datum/data/record() + R.fields["name"] = name + R.fields["id"] = id + R.name = text("Security Record #[id]") + R.fields["criminal"] = "None" + R.fields["mi_crim"] = "None" + R.fields["mi_crim_d"] = "No minor crime convictions." + R.fields["ma_crim"] = "None" + R.fields["ma_crim_d"] = "No major crime convictions." + R.fields["notes"] = "No notes." + data_core.security += R + return R + +/proc/find_security_record(field, value) + return find_record(field, value, data_core.security) + +/proc/find_record(field, value, list/L) + for(var/datum/data/record/R in L) + if(R.fields[field] == value) + return R diff --git a/code/game/area/Dynamic areas.dm b/code/game/area/Dynamic areas.dm index 9d6010f29b4..9198a990ed5 100644 --- a/code/game/area/Dynamic areas.dm +++ b/code/game/area/Dynamic areas.dm @@ -24,15 +24,18 @@ match_tag = "arrivals" match_width = 5 match_height = 4 + requires_power = 0 /area/dynamic/source/lobby_russian name = "\improper Russian Lounge" match_tag = "arrivals" match_width = 5 match_height = 4 + requires_power = 0 /area/dynamic/source/lobby_disco name = "\improper Disco Lounge" match_tag = "arrivals" match_width = 5 - match_height = 4 \ No newline at end of file + match_height = 4 + requires_power = 0 \ No newline at end of file diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index e703f7ba3b2..7d5547f3c45 100644 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -22,6 +22,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station var/poweralm = 1 var/party = null var/radalert = 0 + var/report_alerts = 1 // Should atmos alerts notify the AI/computers level = null name = "Space" icon = 'icons/turf/areas.dmi' @@ -69,7 +70,7 @@ var/list/teleportlocs = list() var/list/turfs = get_area_turfs(AR.type) if(turfs.len) var/turf/picked = pick(turfs) - if (picked.z == 1) + if ((picked.z in config.station_levels)) teleportlocs += AR.name teleportlocs[AR.name] = AR @@ -82,13 +83,13 @@ var/list/ghostteleportlocs = list() /hook/startup/proc/setupGhostTeleportLocs() for(var/area/AR in world) if(ghostteleportlocs.Find(AR.name)) continue - if(istype(AR, /area/turret_protected/aisat) || istype(AR, /area/derelict) || istype(AR, /area/tdome)) + if(istype(AR, /area/tdome)) ghostteleportlocs += AR.name ghostteleportlocs[AR.name] = AR var/list/turfs = get_area_turfs(AR.type) if(turfs.len) var/turf/picked = pick(turfs) - if (picked.z == 1 || picked.z == 5 || picked.z == 3) + if ((picked.z in config.player_levels)) ghostteleportlocs += AR.name ghostteleportlocs[AR.name] = AR @@ -1983,6 +1984,11 @@ area/security/podbay //Traitor Station +/area/traitor + name = "\improper Syndicate Base" + icon_state = "syndie_hall" + report_alerts = 0 + /area/traitor/rnd name = "\improper Syndicate Research and Development" icon_state = "syndie_rnd" @@ -2262,6 +2268,7 @@ area/security/podbay /area/awaycontent name = "space" + report_alerts = 0 /area/awaycontent/a1 icon_state = "awaycontent1" diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 3c04e9cf951..c24ea331bcd 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -52,25 +52,32 @@ InitializeLighting() -/area/proc/poweralert(var/state, var/obj/source as obj) +/area/proc/poweralert(var/state, var/obj/source as obj) if (state != poweralm) poweralm = state if(istype(source)) //Only report power alarms on the z-level where the source is located. var/list/cameras = list() for (var/area/RA in related) for (var/obj/machinery/camera/C in RA) + if(!report_alerts) + break cameras += C if(state == 1) + C.network.Remove("Power Alarms") else C.network.Add("Power Alarms") for (var/mob/living/silicon/aiPlayer in player_list) + if(!report_alerts) + break if(aiPlayer.z == source.z) if (state == 1) aiPlayer.cancelAlarm("Power", src, source) else aiPlayer.triggerAlarm("Power", src, cameras, source) for(var/obj/machinery/computer/station_alert/a in machines) + if(!report_alerts) + break if(a.z == source.z) if(state == 1) a.cancelAlarm("Power", src, source) @@ -107,11 +114,17 @@ for(var/area/RA in related) //updateicon() for(var/obj/machinery/camera/C in RA) + if(!report_alerts) + break cameras += C C.network.Add("Atmosphere Alarms") for(var/mob/living/silicon/aiPlayer in player_list) + if(!report_alerts) + break aiPlayer.triggerAlarm("Atmosphere", src, cameras, src) for(var/obj/machinery/computer/station_alert/a in machines) + if(!report_alerts) + break a.triggerAlarm("Atmosphere", src, cameras, src) air_doors_activated=1 CloseFirelocks() @@ -119,10 +132,16 @@ else if (atmosalm == 2) for(var/area/RA in related) for(var/obj/machinery/camera/C in RA) + if(!report_alerts) + break C.network.Remove("Atmosphere Alarms") for(var/mob/living/silicon/aiPlayer in player_list) + if(!report_alerts) + break aiPlayer.cancelAlarm("Atmosphere", src, src) for(var/obj/machinery/computer/station_alert/a in machines) + if(!report_alerts) + break a.cancelAlarm("Atmosphere", src, src) air_doors_activated=0 OpenFirelocks() @@ -162,11 +181,17 @@ var/list/cameras = list() for(var/area/RA in related) for (var/obj/machinery/camera/C in RA) + if(!report_alerts) + continue cameras.Add(C) C.network.Add("Fire Alarms") for (var/mob/living/silicon/ai/aiPlayer in player_list) + if(!report_alerts) + continue aiPlayer.triggerAlarm("Fire", src, cameras, src) for (var/obj/machinery/computer/station_alert/a in machines) + if(!report_alerts) + continue a.triggerAlarm("Fire", src, cameras, src) /area/proc/firereset() @@ -176,10 +201,16 @@ updateicon() for(var/area/RA in related) for (var/obj/machinery/camera/C in RA) + if(!report_alerts) + continue C.network.Remove("Fire Alarms") for (var/mob/living/silicon/ai/aiPlayer in player_list) + if(!report_alerts) + continue aiPlayer.cancelAlarm("Fire", src, src) for (var/obj/machinery/computer/station_alert/a in machines) + if(!report_alerts) + continue a.cancelAlarm("Fire", src, src) OpenFirelocks() @@ -230,12 +261,11 @@ return /area/proc/updateicon() - if ((fire || eject || party || radalert) && ((!requires_power)?(!requires_power):power_environ))//If it doesn't require power, can still activate this proc. - // Highest priority at the top. - if(radalert && !fire) - icon_state = "radiation" - blend_mode = BLEND_MULTIPLY - else if(fire && !radalert && !eject && !party) + if(radalert) // always show the radiation alert, regardless of power + icon_state = "radiation" + blend_mode = BLEND_MULTIPLY + else if ((fire || eject || party) && ((!requires_power)?(!requires_power):power_environ))//If it doesn't require power, can still activate this proc. + if(fire && !radalert && !eject && !party) icon_state = "red" blend_mode = BLEND_MULTIPLY /*else if(atmosalm && !fire && !eject && !party) @@ -355,7 +385,7 @@ thunk(L) // Ambience goes down here -- make sure to list each area seperately for ease of adding things in later, thanks! Note: areas adjacent to each other should have the same sounds to prevent cutoff when possible.- LastyScratch - if(L && L.client && (L.client.prefs.toggles & SOUND_AMBIENCE)) + if(L && L.client && (L.client.prefs.sound & SOUND_AMBIENCE)) if(!L.client.ambience_playing) L.client.ambience_playing = 1 L << sound('sound/ambience/shipambience.ogg', repeat = 1, wait = 0, volume = 35, channel = 2) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 6dec5fed5c8..61b63bb6a9d 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -1,7 +1,10 @@ +var/global/list/del_profiling = list() +var/global/list/gdel_profiling = list() +var/global/list/ghdel_profiling = list() /atom layer = 2 var/level = 2 - var/flags = FPRINT + var/flags = 0 var/list/fingerprints var/list/fingerprintshidden var/fingerprintslast = null @@ -9,7 +12,6 @@ var/last_bumped = 0 var/pass_flags = 0 var/throwpass = 0 - var/datum/crafting_holder/craft_holder = null var/germ_level = GERM_LEVEL_AMBIENT // The higher the germ level, the more germ on the atom. ///Chemistry. @@ -25,16 +27,18 @@ // Garbage collection var/gc_destroyed=null -/atom/Del() - // Pass to Destroy(). - if(!gc_destroyed) - Destroy() - ..() -/atom/proc/Destroy() - gc_destroyed=world.time +/atom/Destroy() + SetOpacity(0) + if(reagents) + reagents.Destroy() + reagents = null + + // Idea by ChuckTheSheep to make the object even more unreferencable. + invisibility = 101 + /atom/proc/CheckParts() return @@ -242,6 +246,8 @@ its easier to just keep the beam vertical. /atom/proc/blob_act() return +/atom/proc/emag_act() + return /atom/proc/hitby(atom/movable/AM as mob|obj) if (density) @@ -294,7 +300,7 @@ its easier to just keep the beam vertical. add_fibers(M) //He has no prints! - if (M_FINGERPRINTS in M.mutations) + if (FINGERPRINTS in M.mutations) if(fingerprintslast != M.key) fingerprintshidden += "(Has no fingerprints) Real name: [M.real_name], Key: [M.key]" fingerprintslast = M.key @@ -378,8 +384,6 @@ its easier to just keep the beam vertical. M.dna = new /datum/dna(null) M.dna.real_name = M.real_name M.check_dna() - if (!( src.flags ) & FPRINT) - return 0 if(!blood_DNA || !istype(blood_DNA, /list)) //if our list of DNA doesn't exist yet (or isn't a list) initialise it. blood_DNA = list() diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index b80fe3249f6..fdb556a6b64 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -15,13 +15,67 @@ var/mob/pulledby = null var/area/areaMaster - + var/hard_deleted = 0 /atom/movable/New() . = ..() areaMaster = get_area_master(src) +/atom/movable/Destroy() + if(opacity) + if(isturf(loc)) + if(loc:lighting_lumcount > 1) + UpdateAffectingLights() + gcDestroyed = "Bye, world!" + tag = null + loc = null +/* + if(istype(beams) && beams.len) + for(var/obj/effect/beam/B in beams) + if(B && B.target == src) + B.target = null + if(B.master && B.master.target == src) + B.master.target = null + beams.len = 0 +*/ + ..() + +/proc/delete_profile(var/type, code = 0) + if(!ticker || !ticker.current_state < 3) return + switch(code) + if(0) + if (!("[type]" in del_profiling)) + del_profiling["[type]"] = 0 + + del_profiling["[type]"] += 1 + if(1) + if (!("[type]" in ghdel_profiling)) + ghdel_profiling["[type]"] = 0 + + ghdel_profiling["[type]"] += 1 + if(2) + if (!("[type]" in gdel_profiling)) + gdel_profiling["[type]"] = 0 + + gdel_profiling["[type]"] += 1 + if(garbageCollector) + garbageCollector.soft_dels++ + +/atom/movable/Del() + if (gcDestroyed) + garbageCollector.dequeue("\ref[src]") + + if (hard_deleted) + delete_profile("[type]", 1) + else + delete_profile("[type]", 2) + else // direct del calls or nulled explicitly. + delete_profile("[type]", 0) + Destroy() + + ..() + // Used in shuttle movement and AI eye stuff. // Primarily used to notify objects being moved by a shuttle/bluespace fuckup. /atom/movable/proc/setLoc(var/T, var/teleported=0) @@ -99,17 +153,14 @@ src.throw_impact(A,speed) /atom/movable/proc/throw_at(atom/target, range, speed, thrower) - if(!target || !src) return 0 + if(!target || !src || (flags & NODROP)) + return 0 //use a modified version of Bresenham's algorithm to get from the atom's current position to that of the target src.throwing = 1 src.thrower = thrower src.throw_source = get_turf(src) //store the origin turf - if(usr) - if(M_HULK in usr.mutations) - src.throwing = 2 // really strong throw! - var/dist_x = abs(target.x - src.x) var/dist_y = abs(target.y - src.y) @@ -206,9 +257,9 @@ verbs.Cut() return -/atom/movable/overlay/attackby(a, b) +/atom/movable/overlay/attackby(a, b, c) if (src.master) - return src.master.attackby(a, b) + return src.master.attackby(a, b, c) return /atom/movable/overlay/attack_paw(a, b, c) diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm index d4b1a0d44a6..e028702a44e 100644 --- a/code/game/dna/dna2.dm +++ b/code/game/dna/dna2.dm @@ -163,7 +163,7 @@ var/global/list/bad_blocks[0] // Set a DNA UI block's raw value. /datum/dna/proc/SetUIValue(var/block,var/value,var/defer=0) if (block<=0) return - ASSERT(value>=0) + ASSERT(value>0) ASSERT(value<=4095) UI[block]=value dirtyUI=1 @@ -178,7 +178,10 @@ var/global/list/bad_blocks[0] // Set a DNA UI block's value, given a value and a max possible value. // Used in hair and facial styles (value being the index and maxvalue being the len of the hairstyle list) /datum/dna/proc/SetUIValueRange(var/block,var/value,var/maxvalue,var/defer=0) - if (block<=0) return + if (block<=0) + return + if(value == 0) + value = 1 ASSERT(maxvalue<=4095) var/range = (4095 / maxvalue) if(value) diff --git a/code/game/dna/dna2_domutcheck.dm b/code/game/dna/dna2_domutcheck.dm index 6f0e3412f19..545e65b691d 100644 --- a/code/game/dna/dna2_domutcheck.dm +++ b/code/game/dna/dna2_domutcheck.dm @@ -5,6 +5,7 @@ // flags: See below, bitfield. #define MUTCHK_FORCED 1 /proc/domutcheck(var/mob/living/M, var/connected=null, var/flags=0) + for(var/datum/dna/gene/gene in dna_genes) if(!M || !M.dna) return @@ -75,6 +76,14 @@ var/gene_active = (gene.flags & GENE_ALWAYS_ACTIVATE) if(!gene_active) gene_active = M.dna.GetSEState(gene.block) + + var/defaultgenes // Do not mutate inherent species abilities + if(ishuman(M)) + var/mob/living/carbon/human/H = M + defaultgenes = H.species.default_genes + + if((gene in defaultgenes) && gene_active) + return // Prior state var/gene_prior_status = (gene.type in M.active_genes) diff --git a/code/game/dna/dna_misc.dm b/code/game/dna/dna_misc.dm index 13ddefd5514..6b237f5a00e 100644 --- a/code/game/dna/dna_misc.dm +++ b/code/game/dna/dna_misc.dm @@ -410,7 +410,7 @@ for(var/obj/item/W in (H.contents-implants)) if (W==H.w_uniform) // will be teared continue - H.drop_from_inventory(W) + H.unEquip(W) M.monkeyizing = 1 M.canmove = 0 M.icon = null @@ -483,7 +483,7 @@ W.loc = null if(!connected) for(var/obj/item/W in (Mo.contents-implants)) - Mo.drop_from_inventory(W) + Mo.unEquip(W) M.monkeyizing = 1 M.canmove = 0 M.icon = null diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index 5360f08814e..29b1cd1b3d9 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -45,6 +45,7 @@ use_power = 1 idle_power_usage = 50 active_power_usage = 300 + interact_offline = 1 var/locked = 0 var/mob/living/carbon/occupant = null var/obj/item/weapon/reagent_containers/glass/beaker = null @@ -64,7 +65,7 @@ component_parts += new /obj/item/stack/cable_coil(src, 1) component_parts += new /obj/item/stack/cable_coil(src, 1) RefreshParts() - + /obj/machinery/dna_scannernew/upgraded/New() ..() component_parts = list() @@ -190,7 +191,7 @@ if(user.pulling == L) user.pulling = null -/obj/machinery/dna_scannernew/attackby(var/obj/item/weapon/item as obj, var/mob/user as mob) +/obj/machinery/dna_scannernew/attackby(var/obj/item/weapon/item as obj, var/mob/user as mob, params) if(istype(item, /obj/item/weapon/screwdriver)) if(occupant) user << "The maintenance panel is locked." @@ -232,7 +233,7 @@ return put_in(G.affecting) src.add_fingerprint(user) - del(G) + qdel(G) return /obj/machinery/dna_scannernew/proc/put_in(var/mob/M) @@ -308,7 +309,7 @@ if(prob(75)) for(var/atom/movable/A as mob|obj in src) A.loc = src.loc - del(src) + qdel(src) /obj/machinery/computer/scan_consolenew name = "DNA Modifier Access Console" @@ -337,7 +338,7 @@ active_power_usage = 400 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) +/obj/machinery/computer/scan_consolenew/attackby(obj/item/I as obj, mob/user as mob, params) if (istype(I, /obj/item/weapon/disk/data)) //INSERT SOME diskS if (!src.disk) user.drop_item() @@ -366,7 +367,7 @@ /obj/machinery/computer/scan_consolenew/blob_act() if(prob(75)) - del(src) + qdel(src) /obj/machinery/computer/scan_consolenew/power_change() if(stat & BROKEN) @@ -503,7 +504,7 @@ occupantData["name"] = connected.occupant.name occupantData["stat"] = connected.occupant.stat occupantData["isViableSubject"] = 1 - if ((M_NOCLONE in connected.occupant.mutations && connected.scan_level < 3) || !src.connected.occupant.dna) + if ((NOCLONE in connected.occupant.mutations && connected.scan_level < 3) || !src.connected.occupant.dna) occupantData["isViableSubject"] = 0 occupantData["health"] = connected.occupant.health occupantData["maxHealth"] = connected.occupant.maxHealth @@ -842,7 +843,7 @@ return 1 if (bufferOption == "transfer") - if (!src.connected.occupant || (M_NOCLONE in src.connected.occupant.mutations && connected.scan_level < 3) || !src.connected.occupant.dna) + if (!src.connected.occupant || (NOCLONE in src.connected.occupant.mutations && connected.scan_level < 3) || !src.connected.occupant.dna) return irradiating = 2 diff --git a/code/game/dna/genes/disabilities.dm b/code/game/dna/genes/disabilities.dm index eaf4500359e..0431d666c53 100644 --- a/code/game/dna/genes/disabilities.dm +++ b/code/game/dna/genes/disabilities.dm @@ -55,7 +55,7 @@ name="Hallucinate" activation_message="Your mind says 'Hello'." deactivation_message ="Sanity returns. Or does it?" - mutation=M_HALLUCINATE + mutation=HALLUCINATE New() block=HALLUCINATIONBLOCK @@ -82,7 +82,7 @@ name="Clumsiness" activation_message="You feel lightheaded." deactivation_message ="You regain some control of your movements" - mutation=M_CLUMSY + mutation=CLUMSY New() block=CLUMSYBLOCK @@ -148,4 +148,14 @@ block=LISPBLOCK OnSay(var/mob/M, var/message) - return replacetext(message,"s","th") \ No newline at end of file + return replacetext(message,"s","th") + +/datum/dna/gene/disability/comic + name = "Comic" + desc = "This will only bring death and destruction." + activation_message = "Uh oh!" + deactivation_message = "Well thank god that's over with." + mutation=COMIC + + New() + block = COMICBLOCK diff --git a/code/game/dna/genes/goon_disabilities.dm b/code/game/dna/genes/goon_disabilities.dm index c0973e2206d..4f8af67358b 100644 --- a/code/game/dna/genes/goon_disabilities.dm +++ b/code/game/dna/genes/goon_disabilities.dm @@ -12,6 +12,7 @@ desc = "Completely shuts down the speech center of the subject's brain." activation_message = "You feel unable to express yourself at all." deactivation_message = "You feel able to speak freely again." + sdisability = 1 New() ..() @@ -57,7 +58,7 @@ activation_message = "You feel blubbery and lethargic!" deactivation_message = "You feel fit!" - mutation = M_OBESITY + mutation = OBESITY New() ..() @@ -219,7 +220,7 @@ deactivation_message = "Your stomach stops acting up. Phew!" instability=2 - mutation = M_TOXIC_FARTS + mutation = TOXIC_FARTS New() ..() @@ -237,7 +238,7 @@ activation_message = "You feel buff!" deactivation_message = "You feel wimpy and weak." - mutation = M_STRONG + mutation = STRONG New() ..() @@ -335,7 +336,7 @@ if(L) usr.attack_log += text("\[[time_stamp()]\] [usr.real_name] ([usr.ckey]) cast the spell [name] on [L.real_name] ([L.ckey]).") - msg_admin_attack("[usr.real_name] ([usr.ckey]) has cast the spell [name] on [L.real_name] ([L.ckey]) ()") + msg_admin_attack("[usr.real_name] ([usr.ckey]) has cast the spell [name] on [L.real_name] ([L.ckey]) (JMP)") L.adjust_fire_stacks(0.5) L.visible_message("\red [L.name] suddenly bursts into flames!") diff --git a/code/game/dna/genes/goon_powers.dm b/code/game/dna/genes/goon_powers.dm index e421a9594f8..8f57ce1e6cd 100644 --- a/code/game/dna/genes/goon_powers.dm +++ b/code/game/dna/genes/goon_powers.dm @@ -6,7 +6,7 @@ activation_messages=list("You feel unusually sober.") deactivation_messages = list("You feel like you could use a stiff drink.") - mutation=M_SOBER + mutation=SOBER New() block=SOBERBLOCK @@ -19,7 +19,7 @@ deactivation_messages = list("You feel oddly exposed.") instability=2 - mutation=M_PSY_RESIST + mutation=PSY_RESIST New() block=PSYRESISTBLOCK @@ -47,6 +47,7 @@ desc = "Enables the subject to bend low levels of light around themselves, creating a cloaking effect." activation_messages = list("You begin to fade into the shadows.") deactivation_messages = list("You become fully visible.") + activation_prob=10 New() block=SHADOWBLOCK @@ -66,6 +67,7 @@ desc = "The subject becomes able to subtly alter light patterns to become invisible, as long as they remain still." activation_messages = list("You feel one with your surroundings.") deactivation_messages = list("You feel oddly exposed.") + activation_prob=10 New() block=CHAMELEONBLOCK @@ -149,7 +151,7 @@ usr << "\red This will only work on normal organic beings." return - if (M_RESIST_COLD in C.mutations) + if (RESIST_COLD in C.mutations) C.visible_message("\red A cloud of fine ice crystals engulfs [C.name], but disappears almost instantly!") return var/handle_suit = 0 @@ -162,12 +164,12 @@ H.visible_message("\red [usr] sprays a cloud of fine ice crystals, engulfing [H]!", "[usr] sprays a cloud of fine ice crystals over your [H.head]'s visor.") log_admin("[ckey(usr.key)] has used cryokinesis on [ckey(C.key)], internals yes, suit yes") - msg_admin_attack("[usr.real_name] ([usr.ckey]) has cast cryokinesis on [C.real_name] ([C.ckey]), ()") + msg_admin_attack("[usr.real_name] ([usr.ckey]) has cast cryokinesis on [C.real_name] ([C.ckey]), (JMP)") else H.visible_message("\red [usr] sprays a cloud of fine ice crystals engulfing, [H]!", "[usr] sprays a cloud of fine ice crystals cover your [H.head]'s visor and make it into your air vents!.") log_admin("[usr.real_name] ([ckey(usr.key)]) has used cryokinesis on [C.real_name] ([ckey(C.key)]), ()") - msg_admin_attack("[usr.real_name] ([usr.ckey]) has cast cryokinesis on [C.real_name] ([C.ckey]), ()") + msg_admin_attack("[usr.real_name] ([usr.ckey]) has cast cryokinesis on [C.real_name] ([C.ckey]), (JMP)") H.bodytemperature = max(0, H.bodytemperature - 50) H.adjustFireLoss(5) if(!handle_suit) @@ -177,7 +179,7 @@ C.visible_message("\red [usr] sprays a cloud of fine ice crystals, engulfing [C]!") log_admin("[ckey(usr.key)] has used cryokinesis on [ckey(C.key)], internals no, suit no") - msg_admin_attack("[usr.real_name] ([usr.ckey]) has cast cryokinesis on [C.real_name] ([C.ckey]), ()") + msg_admin_attack("[usr.real_name] ([usr.ckey]) has cast cryokinesis on [C.real_name] ([C.ckey]), (JMP)") //playsound(usr.loc, 'bamf.ogg', 50, 0) @@ -316,7 +318,7 @@ else usr.visible_message("\red [usr] eats \the [the_item].") playsound(usr.loc, 'sound/items/eatfood.ogg', 50, 0) - del(the_item) + qdel(the_item) doHeal(usr) return @@ -392,7 +394,7 @@ else usr.pixel_y -= 8 sleep(1) - if (M_FAT in usr.mutations && prob(66)) + if (FAT in usr.mutations && prob(66)) usr.visible_message("\red [usr.name] crashes due to their heavy weight!") //playsound(usr.loc, 'zhit.wav', 50, 1) usr.weakened += 10 @@ -481,7 +483,7 @@ activation_messages = list("You suddenly notice more about others than you did before.") deactivation_messages = list("You no longer feel able to sense intentions.") instability=1 - mutation=M_EMPATH + mutation=EMPATH New() ..() @@ -514,7 +516,7 @@ usr << "\red You may only use this on other organic beings." return - if (M_PSY_RESIST in M.mutations) + if (PSY_RESIST in M.mutations) usr << "\red You can't see into [M.name]'s mind at all!" return @@ -578,7 +580,7 @@ usr << "\blue Numbers: You sense the number[numbers.len>1?"s":""] [english_list(numbers)] [numbers.len>1?"are":"is"] important to [M.name]." usr << "\blue Thoughts: [M.name] is currently [thoughts]." - if (M_EMPATH in M.mutations) + if (EMPATH in M.mutations) M << "\red You sense [usr.name] reading your mind." else if (prob(5) || M.mind.assigned_role=="Chaplain") M << "\red You sense someone intruding upon your thoughts..." @@ -594,7 +596,7 @@ deactivation_messages = list("You no longer feel gassy. What a relief!") instability=1 - mutation = M_SUPER_FART + mutation = SUPER_FART New() ..() diff --git a/code/game/dna/genes/monkey.dm b/code/game/dna/genes/monkey.dm index e1faba73a75..03ca9880c2c 100644 --- a/code/game/dna/genes/monkey.dm +++ b/code/game/dna/genes/monkey.dm @@ -22,7 +22,7 @@ for(var/obj/item/W in (H.contents-implants)) if (W==H.w_uniform) // will be teared continue - H.drop_from_inventory(W) + H.unEquip(W) M.monkeyizing = 1 M.canmove = 0 M.icon = null @@ -33,7 +33,7 @@ animation.master = src flick("h2monkey", animation) sleep(48) - del(animation) + qdel(animation) var/mob/living/carbon/monkey/O = null @@ -56,7 +56,7 @@ for(var/obj/T in (M.contents-implants)) - del(T) + qdel(T) O.loc = M.loc @@ -78,7 +78,7 @@ I.loc = O I.implanted = O // O.update_icon = 1 //queue a full icon update at next life() call - del(M) + qdel(M) return /datum/dna/gene/monkey/deactivate(var/mob/living/M, var/connected, var/flags) @@ -93,7 +93,7 @@ W.loc = null if(!connected) for(var/obj/item/W in (Mo.contents-implants)) - Mo.drop_from_inventory(W) + Mo.unEquip(W) M.monkeyizing = 1 M.canmove = 0 M.icon = null diff --git a/code/game/dna/genes/powers.dm b/code/game/dna/genes/powers.dm index 81d20456736..d74379c3d8b 100644 --- a/code/game/dna/genes/powers.dm +++ b/code/game/dna/genes/powers.dm @@ -5,8 +5,9 @@ /datum/dna/gene/basic/nobreath name="No Breathing" activation_messages=list("You feel no need to breathe.") - mutation=M_NO_BREATH + mutation=NO_BREATH instability=2 + activation_prob=10 New() block=NOBREATHBLOCK @@ -15,7 +16,7 @@ /datum/dna/gene/basic/regenerate name="Regenerate" activation_messages=list("You feel better.") - mutation=M_REGEN + mutation=REGEN instability=2 New() @@ -24,7 +25,7 @@ /datum/dna/gene/basic/increaserun name="Super Speed" activation_messages=list("Your leg muscles pulsate.") - mutation=M_RUN + mutation=RUN instability=1 New() @@ -34,7 +35,7 @@ /datum/dna/gene/basic/heat_resist name="Heat Resistance" activation_messages=list("Your skin is icy to the touch.") - mutation=M_RESIST_HEAT + mutation=RESIST_HEAT instability=2 New() @@ -45,7 +46,7 @@ return !(/datum/dna/gene/basic/cold_resist in M.active_genes) // Probability check var/_prob = 15 - if(M_RESIST_COLD in M.mutations) + if(RESIST_COLD in M.mutations) _prob=5 if(probinj(_prob,(flags&MUTCHK_FORCED))) return 1 @@ -56,7 +57,7 @@ /datum/dna/gene/basic/cold_resist name="Cold Resistance" activation_messages=list("Your body is filled with warmth.") - mutation=M_RESIST_COLD + mutation=RESIST_COLD instability=2 New() @@ -67,7 +68,7 @@ return !(/datum/dna/gene/basic/heat_resist in M.active_genes) // Probability check var/_prob=30 - if(M_RESIST_HEAT in M.mutations) + if(RESIST_HEAT in M.mutations) _prob=5 if(probinj(_prob,(flags&MUTCHK_FORCED))) return 1 @@ -78,7 +79,7 @@ /datum/dna/gene/basic/noprints name="No Prints" activation_messages=list("Your fingers feel numb.") - mutation=M_FINGERPRINTS + mutation=FINGERPRINTS instability=1 New() @@ -87,7 +88,7 @@ /datum/dna/gene/basic/noshock name="Shock Immunity" activation_messages=list("Your skin feels strange.") - mutation=M_NO_SHOCK + mutation=NO_SHOCK instability=2 New() @@ -96,7 +97,7 @@ /datum/dna/gene/basic/midget name="Midget" activation_messages=list("Your skin feels rubbery.") - mutation=M_DWARF + mutation=DWARF instability=1 New() @@ -104,7 +105,7 @@ can_activate(var/mob/M,var/flags) // Can't be big and small. - if(M_HULK in M.mutations) + if(HULK in M.mutations) return 0 return ..(M,flags) @@ -112,10 +113,57 @@ ..(M,connected,flags) M.pass_flags |= 1 + +// OLD HULK BEHAVIOR +/datum/dna/gene/basic/hulk + name="Hulk" + activation_messages=list("Your muscles hurt.") + mutation=HULK + activation_prob=5 + + New() + block=HULKBLOCK + + can_activate(var/mob/M,var/flags) + // Can't be big AND small. + if(DWARF in M.mutations) + return 0 + return ..(M,flags) + + activate(var/mob/M, var/connected, var/flags) + ..() + var/status = CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH + M.status_flags &= ~status + + deactivate(var/mob/M, var/connected, var/flags) + ..() + M.status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH + + OnDrawUnderlays(var/mob/M,var/g,var/fat) + if(HULK in M.mutations) + if(fat) + return "hulk_[fat]_s" + else + return "hulk_[g]_s" + return 0 + + OnMobLife(var/mob/living/carbon/human/M) + if(!istype(M)) return + if ((HULK in M.mutations) && M.health <= 25) + M.mutations.Remove(HULK) + M.dna.SetSEState(HULKBLOCK,0) + M.update_mutations() //update our mutation overlays + M.update_body() + M.status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH //temporary fix until the problem can be solved. + M << "You suddenly feel very weak." + M.Weaken(3) + M.emote("collapse") + /datum/dna/gene/basic/xray name="X-Ray Vision" activation_messages=list("The walls suddenly disappear.") - mutation=M_XRAY + mutation=XRAY + activation_prob=10 instability=2 New() @@ -124,8 +172,8 @@ /datum/dna/gene/basic/tk name="Telekenesis" activation_messages=list("You feel smarter.") - mutation=M_TK - activation_prob=15 + mutation=TK + activation_prob=10 instability=5 New() diff --git a/code/game/dna/genes/vg_disabilities.dm b/code/game/dna/genes/vg_disabilities.dm index ad6c103f429..6cb2c6f6ce8 100644 --- a/code/game/dna/genes/vg_disabilities.dm +++ b/code/game/dna/genes/vg_disabilities.dm @@ -17,7 +17,7 @@ message = replacetext(message,"!","!!") return uppertext(message) - +/* BROKEN WITH NEW SAYCODE /datum/dna/gene/disability/speech/whisper name = "Quiet" desc = "Damages the subjects vocal cords" @@ -30,13 +30,13 @@ can_activate(var/mob/M,var/flags) // No loud whispering. - if(M_LOUD in M.mutations) + if(LOUD in M.mutations) return 0 return ..(M,flags) OnSay(var/mob/M, var/message) M.whisper(message) - +*/ /datum/dna/gene/disability/dizzy name = "Dizzy" @@ -51,5 +51,5 @@ OnMobLife(var/mob/living/carbon/human/M) if(!istype(M)) return - if(M_DIZZY in M.mutations) + if(DIZZY in M.mutations) M.Dizzy(300) diff --git a/code/game/dna/genes/vg_powers.dm b/code/game/dna/genes/vg_powers.dm index b4bdee1b464..f0a5d1dbd18 100644 --- a/code/game/dna/genes/vg_powers.dm +++ b/code/game/dna/genes/vg_powers.dm @@ -2,7 +2,7 @@ This is /vg/'s nerf for hulk. Feel free to steal it. Obviously, requires DNA2. -*/ + // When hulk was first applied (world.time). /mob/living/carbon/human/var/hulk_time=0 @@ -26,12 +26,12 @@ Obviously, requires DNA2. can_activate(var/mob/M,var/flags) // Can't be big AND small. - if(M_DWARF in M.mutations) + if(DWARF in M.mutations) return 0 return ..(M,flags) OnDrawUnderlays(var/mob/M,var/g,var/fat) - if(M_HULK in M.mutations) + if(HULK in M.mutations) if(fat) return "hulk_[fat]_s" else @@ -40,11 +40,11 @@ Obviously, requires DNA2. OnMobLife(var/mob/living/carbon/human/M) if(!istype(M)) return - if(M_HULK in M.mutations) + if(HULK in M.mutations) var/timeleft=M.hulk_time - world.time if(M.health <= 25 || timeleft <= 0) M.hulk_time=0 // Just to be sure. - M.mutations.Remove(M_HULK) + M.mutations.Remove(HULK) //M.dna.SetSEState(HULKBLOCK,0) M.update_mutations() //update our mutation overlays M.update_body() @@ -78,13 +78,13 @@ Obviously, requires DNA2. return var/mob/living/carbon/human/M=usr M.hulk_time = world.time + HULK_DURATION - M.mutations.Add(M_HULK) + M.mutations.Add(HULK) M.update_mutations() //update our mutation overlays M.update_body() //M.say(pick("",";")+pick("HULK MAD","YOU MADE HULK ANGRY")) // Just a note to security. message_admins("[key_name(usr)] has hulked out! ([formatJumpTo(usr)])") return - +*/ ///////////////////Vanilla Morph//////////////////////////////////// @@ -98,7 +98,7 @@ Obviously, requires DNA2. deactivation_messages = list("You body feels normal.") - mutation=M_MORPH + mutation=MORPH instability=2 New() @@ -197,7 +197,7 @@ Obviously, requires DNA2. /datum/dna/gene/basic/grant_spell/remotetalk name="Telepathy" activation_messages=list("You expand your mind outwards.") - mutation=M_REMOTE_TALK + mutation=REMOTE_TALK instability=1 spelltype =/obj/effect/proc_holder/spell/wizard/targeted/remotetalk @@ -222,19 +222,19 @@ Obviously, requires DNA2. /obj/effect/proc_holder/spell/wizard/targeted/remotetalk/choose_targets(mob/user = usr) var/list/targets = new /list() var/list/validtargets = new /list() - for(var/mob/M in living_mob_list) + for(var/mob/M in living_mob_list) if(M && M.mind) var/special_role = M.mind.special_role if (special_role == "Wizard" || special_role == "Ninja" || special_role == "Syndicate" || special_role == "Syndicate Commando" || special_role == "Vox Raider" || special_role == "Alien") continue - + validtargets += M - + if(!validtargets.len || validtargets.len == 1) usr << "There are no valid targets!" start_recharge() return - + targets += input("Choose the target to talk to.", "Targeting") as mob in validtargets perform(targets) @@ -244,7 +244,7 @@ Obviously, requires DNA2. var/say = strip_html(input("What do you wish to say")) for(var/mob/living/target in targets) - if(M_REMOTE_TALK in target.mutations) + if(REMOTE_TALK in target.mutations) target.show_message("\blue You hear [usr.real_name]'s voice: [say]") else target.show_message("\blue You hear a voice that seems to echo around the room: [say]") @@ -257,7 +257,7 @@ Obviously, requires DNA2. /datum/dna/gene/basic/grant_spell/remoteview name="Remote Viewing" activation_messages=list("Your mind expands.") - mutation=M_REMOTE_VIEW + mutation=REMOTE_VIEW instability=3 spelltype =/obj/effect/proc_holder/spell/wizard/targeted/remoteview @@ -280,10 +280,10 @@ Obviously, requires DNA2. icon_power_button = "genetic_view" /obj/effect/proc_holder/spell/wizard/targeted/remoteview/choose_targets(mob/user = usr) - var/list/targets = living_mob_list + var/list/targets = living_mob_list var/list/remoteviewers = new /list() for(var/mob/M in targets) - if(M_REMOTE_VIEW in M.mutations) + if(REMOTE_VIEW in M.mutations) remoteviewers += M if(!remoteviewers.len || remoteviewers.len == 1) usr << "No valid targets with remote view were found!" @@ -316,7 +316,7 @@ Obviously, requires DNA2. for(var/mob/living/L in targets) if(ishuman(L)) var/mob/living/carbon/human/H = L - if(M_PSY_RESIST in H.mutations) + if(PSY_RESIST in H.mutations) continue target = L diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm index 46482dc9ff6..5eb2ad4ecd6 100644 --- a/code/game/gamemodes/antag_spawner.dm +++ b/code/game/gamemodes/antag_spawner.dm @@ -26,7 +26,7 @@ if(!checking) checking = 1 user << "The device is now checking for possible candidates." - get_candidate_answer(user, get_candidates(BE_OPERATIVE,,"operative","Syndicate")) + get_candidate_answer(user, get_candidates(BE_OPERATIVE)) else user << "The device is already checking for possible candidates." return diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm index ccbff9b326d..886ab3b5863 100644 --- a/code/game/gamemodes/blob/blob.dm +++ b/code/game/gamemodes/blob/blob.dm @@ -58,7 +58,7 @@ var/list/blob_nodes = list() /datum/game_mode/blob/proc/get_nuke_code() var/nukecode = "ERROR" for(var/obj/machinery/nuclearbomb/bomb in world) - if(bomb && bomb.r_code && bomb.z == 1) + if(bomb && bomb.r_code && (bomb.z in config.station_levels)) nukecode = bomb.r_code return nukecode @@ -92,7 +92,7 @@ var/list/blob_nodes = list() if(directory[ckey(blob.key)]) blob_client = directory[ckey(blob.key)] location = get_turf(C) - if(location.z != 1 || istype(location, /turf/space)) + if(!(location.z in config.station_levels) || istype(location, /turf/space)) location = null C.gib() @@ -175,21 +175,17 @@ var/list/blob_nodes = list() return if (1) - command_alert("Nanotrasen has issued a directive 7-10 for [station_name()]. The station is to be considered quarantined.", "Biohazard Alert") - for(var/mob/M in player_list) - if(!istype(M,/mob/new_player)) - M << sound('sound/AI/blob_confirmed.ogg') + command_announcement.Announce("Nanotrasen has issued a directive 7-10 for [station_name()]. The station is to be considered quarantined.", "Biohazard Alert", new_sound = 'sound/AI/blob_confirmed.ogg') return if (2) - command_alert("The biohazard has grown out of control and will soon reach critical mass. Activate the nuclear failsafe to maintain quarantine. The Nuclear Authentication Code is [get_nuke_code()] ", "Biohazard Alert") + command_announcement.Announce("The biohazard has grown out of control and will soon reach critical mass. Activate the nuclear failsafe to maintain quarantine. The Nuclear Authentication Code is [get_nuke_code()] ", "Biohazard Alert", new_sound = 'sound/effects/siren.ogg') set_security_level("gamma") var/obj/machinery/door/airlock/vault/V = locate(/obj/machinery/door/airlock/vault) in world - if(V && V.z == 1) + if(V && (V.z in config.station_levels)) V.locked = 0 V.update_icon() send_intercept(2) - spawn(10) world << sound('sound/effects/siren.ogg') return return diff --git a/code/game/gamemodes/blob/blob_finish.dm b/code/game/gamemodes/blob/blob_finish.dm index 868cd62a5f6..1c3e57d2e00 100644 --- a/code/game/gamemodes/blob/blob_finish.dm +++ b/code/game/gamemodes/blob/blob_finish.dm @@ -62,7 +62,7 @@ datum/game_mode/proc/auto_declare_completion_blob() if (istype(T, /turf/space)) numSpace += 1 else if(istype(T, /turf)) - if (M.z!=1) + if (!(M.z in config.station_levels)) numOffStation += 1 else numAlive += 1 diff --git a/code/game/gamemodes/blob/blob_report.dm b/code/game/gamemodes/blob/blob_report.dm index 4b8dd6bf31d..20feb9044cb 100644 --- a/code/game/gamemodes/blob/blob_report.dm +++ b/code/game/gamemodes/blob/blob_report.dm @@ -61,7 +61,7 @@ proc/count() for(var/turf/T in world) - if(T.z != 1) + if(!(T.z in config.station_levels)) continue if(istype(T,/turf/simulated/floor)) @@ -83,7 +83,7 @@ src.r_wall += 1 for(var/obj/O in world) - if(O.z != 1) + if(!(O.z in config.station_levels)) continue if(istype(O, /obj/structure/window)) diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm index fb5fd71928b..2dd69860b14 100644 --- a/code/game/gamemodes/blob/blobs/core.dm +++ b/code/game/gamemodes/blob/blobs/core.dm @@ -72,7 +72,7 @@ var/list/candidates = list() if(!new_overmind) - candidates = get_candidates(BE_BLOB,,"blob","Syndicate") + candidates = get_candidates(BE_BLOB) if(candidates.len) C = pick(candidates) else diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm index 8316c570f9a..37b70de409a 100644 --- a/code/game/gamemodes/blob/overmind.dm +++ b/code/game/gamemodes/blob/overmind.dm @@ -14,13 +14,26 @@ var/obj/effect/blob/core/blob_core = null // The blob overmind's core var/blob_points = 0 var/max_blob_points = 100 + var/ghostimage = null /mob/camera/blob/New() var/new_name = "[initial(name)] ([rand(1, 999)])" name = new_name real_name = new_name + + ghostimage = image(src.icon,src,src.icon_state) + ghost_darkness_images |= ghostimage //so ghosts can see the blob cursor when they disable darkness + updateallghostimages() + ..() +/mob/camera/blob/Destroy() + if (ghostimage) + ghost_darkness_images -= ghostimage + qdel(ghostimage) + ghostimage = null; + updateallghostimages() + /mob/camera/blob/Login() ..() sync_mind() @@ -65,13 +78,13 @@ /mob/camera/blob/proc/blob_talk(message) log_say("[key_name(src)] : [message]") - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) + message = trim(sanitize(copytext(message, 1, MAX_MESSAGE_LEN))) if (!message) return - var/message_a = say_quote(message) - var/rendered = "Blob Telepathy, [name] [message_a]" + var/verb = "states," + var/rendered = "Blob Telepathy, [name] [verb] \"[message]\"" for (var/mob/camera/blob/S in world) if(istype(S)) @@ -79,7 +92,7 @@ for (var/mob/M in dead_mob_list) if(!istype(M,/mob/new_player) && !istype(M,/mob/living/carbon/brain)) //No meta-evesdropping - rendered = "Blob Telepathy, [name] (Follow) [message_a]" + rendered = "Blob Telepathy, [name] (follow) [verb] \"[message]\"" M.show_message(rendered, 2) /mob/camera/blob/emote(var/act,var/m_type=1,var/message = null) diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index 9fdcc7ce7ba..7c336b0acab 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -129,7 +129,9 @@ return 0 - attackby(var/obj/item/weapon/W, var/mob/user) + attackby(var/obj/item/weapon/W, var/mob/living/user, params) + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) playsound(get_turf(src), 'sound/effects/attackblob.ogg', 50, 1) src.visible_message("\red The [src.name] has been attacked with \the [W][(user ? " by [user]." : ".")]") var/damage = 0 @@ -144,6 +146,19 @@ health -= damage update_icon() return + + attack_animal(mob/living/simple_animal/M as mob) + M.changeNext_move(CLICK_CD_MELEE) + M.do_attack_animation(src) + playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1) + src.visible_message("The [src.name] has been attacked by \the [M]!") + var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) + if(!damage) // Avoid divide by zero errors + return + damage /= max(src.brute_resist, 1) + health -= damage + update_icon() + return proc/change_to(var/type) if(!ispath(type)) diff --git a/code/game/gamemodes/borer/borer.dm b/code/game/gamemodes/borer/borer.dm index 7ec3801be02..f5948f3a683 100644 --- a/code/game/gamemodes/borer/borer.dm +++ b/code/game/gamemodes/borer/borer.dm @@ -39,7 +39,7 @@ return 0 // not enough candidates for borer for(var/obj/machinery/atmospherics/unary/vent_pump/v in world) - if(!v.welded && v.z == STATION_Z) // No more spawning in atmos. Assuming the mappers did their jobs, anyway. + if(!v.welded && (v.z in config.station_levels)) found_vents.Add(v) // for each 2 possible borers, add one borer and one host diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index 27bae141374..8edd5e0c664 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -9,7 +9,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" config_tag = "changeling" restricted_jobs = list("AI", "Cyborg") protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Blueshield", "Nanotrasen Representative", "Security Pod Pilot", "Magistrate", "Brig Physician", "Internal Affairs Agent") - protected_species = list("Machine") + protected_species = list("Machine", "Slime People") required_players = 2 required_players_secret = 10 required_enemies = 1 @@ -90,31 +90,55 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" var/datum/objective/absorb/absorb_objective = new absorb_objective.owner = changeling - absorb_objective.gen_amount_goal(2, 3) + absorb_objective.gen_amount_goal(6, 8) changeling.objectives += absorb_objective - var/datum/objective/assassinate/kill_objective = new - kill_objective.owner = changeling - kill_objective.find_target() - changeling.objectives += kill_objective + if(prob(60)) + var/datum/objective/steal/steal_objective = new + steal_objective.owner = changeling + steal_objective.find_target() + changeling.objectives += steal_objective + else + var/datum/objective/debrain/debrain_objective = new + debrain_objective.owner = changeling + debrain_objective.find_target() + changeling.objectives += debrain_objective - var/datum/objective/steal/steal_objective = new - steal_objective.owner = changeling - steal_objective.find_target() - changeling.objectives += steal_objective + var/list/active_ais = active_ais() + if(active_ais.len && prob(4)) // Leaving this at a flat chance for now, problems with the num_players() proc due to latejoin antags. + var/datum/objective/destroy/destroy_objective = new + destroy_objective.owner = changeling + destroy_objective.find_target() + changeling.objectives += destroy_objective + else + var/datum/objective/assassinate/kill_objective = new + kill_objective.owner = changeling + kill_objective.find_target() + changeling.objectives += kill_objective + if (!(locate(/datum/objective/escape) in changeling.objectives)) + var/datum/objective/escape/escape_with_identity/identity_theft = new + identity_theft.owner = changeling + identity_theft.target = kill_objective.target + if(identity_theft.target && identity_theft.target.current) + identity_theft.target_real_name = kill_objective.target.current.real_name //Whoops, forgot this. + var/mob/living/carbon/human/H = identity_theft.target.current + if(H.species && H.species.flags && H.species.flags & NO_SCAN) // For species that can't be absorbed - should default to an escape objective instead + return + else + identity_theft.explanation_text = "Escape on the shuttle or an escape pod with the identity of [identity_theft.target_real_name], the [identity_theft.target.assigned_role] while wearing their identification card." + changeling.objectives += identity_theft - switch(rand(1,100)) - if(1 to 80) - if (!(locate(/datum/objective/escape) in changeling.objectives)) - var/datum/objective/escape/escape_objective = new - escape_objective.owner = changeling - changeling.objectives += escape_objective + if (!(locate(/datum/objective/escape) in changeling.objectives)) + if(prob(70)) + var/datum/objective/escape/escape_objective = new + escape_objective.owner = changeling + changeling.objectives += escape_objective else - if (!(locate(/datum/objective/survive) in changeling.objectives)) - var/datum/objective/survive/survive_objective = new - survive_objective.owner = changeling - changeling.objectives += survive_objective + var/datum/objective/escape/escape_with_identity/identity_theft = new + identity_theft.owner = changeling + identity_theft.find_target() + changeling.objectives += identity_theft return /datum/game_mode/proc/greet_changeling(var/datum/mind/changeling, var/you_are=1) @@ -126,7 +150,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" if (changeling.current.mind) if (changeling.current.mind.assigned_role == "Clown") changeling.current << "You have evolved beyond your clownish nature, allowing you to wield weapons without harming yourself." - changeling.current.mutations.Remove(M_CLUMSY) + changeling.current.mutations.Remove(CLUMSY) var/obj_count = 1 for(var/datum/objective/objective in changeling.objectives) @@ -162,7 +186,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" /datum/game_mode/proc/auto_declare_completion_changeling() if(changelings.len) - var/text = "The changelings were:" + var/text = "The changelings were:" for(var/datum/mind/changeling in changelings) var/changelingwin = 1 @@ -181,7 +205,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" //Removed sanity if(changeling) because we -want- a runtime to inform us that the changelings list is incorrect and needs to be fixed. text += "
Changeling ID: [changeling.changeling.changelingID]." - text += "
Genomes Absorbed: [changeling.changeling.absorbedcount]" + text += "
Genomes Extracted: [changeling.changeling.absorbedcount]" if(changeling.objectives.len) var/count = 1 @@ -209,19 +233,25 @@ 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/list/protected_dna = list() //DNA that is not lost when capacity is otherwise full. + var/dna_max = 4 //How many extra DNA strands the changeling can store for transformation. + var/absorbedcount = 1 //Would require at least 1 sample to take on the form of a human var/chem_charges = 20 var/chem_recharge_rate = 0.5 + var/chem_recharge_slowdown = 0 var/chem_storage = 50 - var/sting_range = 1 + var/sting_range = 2 var/changelingID = "Changeling" var/geneticdamage = 0 var/isabsorbing = 0 - var/geneticpoints = 5 + var/geneticpoints = 10 var/purchasedpowers = list() var/mimicing = "" + var/canrespec = 0 + var/changeling_speak = 0 + var/datum/dna/chosen_dna + var/obj/effect/proc_holder/changeling/sting/chosen_sting /datum/changeling/New(var/gender=FEMALE) ..() @@ -234,16 +264,52 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" changelingID = "[honorific] [changelingID]" else changelingID = "[honorific] [rand(1,999)]" + absorbed_dna.len = dna_max /datum/changeling/proc/regenerate() - chem_charges = min(max(0, chem_charges+chem_recharge_rate), chem_storage) + chem_charges = min(max(0, chem_charges + chem_recharge_rate - chem_recharge_slowdown), chem_storage) geneticdamage = max(0, geneticdamage-1) /datum/changeling/proc/GetDNA(var/dna_owner) - var/datum/dna/chosen_dna - for(var/datum/dna/DNA in absorbed_dna) + for(var/datum/dna/DNA in (absorbed_dna + protected_dna)) if(dna_owner == DNA.real_name) - chosen_dna = DNA - break - return chosen_dna + return DNA + +/datum/changeling/proc/has_dna(var/datum/dna/tDNA) + for(var/datum/dna/D in (absorbed_dna + protected_dna)) + if(tDNA.unique_enzymes == D.unique_enzymes && tDNA.uni_identity == D.uni_identity && tDNA.species == D.species) + return 1 + return 0 + +/datum/changeling/proc/can_absorb_dna(var/mob/living/carbon/user, var/mob/living/carbon/target) + if(absorbed_dna[1] == user.dna)//If our current DNA is the stalest, we gotta ditch it. + user << "We have reached our capacity to store genetic information! We must transform before absorbing more." + return + + if(!target || !target.dna) + user << "This creature does not have any DNA." + return + + var/mob/living/carbon/human/T = target + if(!istype(T)) + user << "[T] is not compatible with our biology." + return + + if((NOCLONE || SKELETON || HUSK) in T.mutations) + user << "DNA of [target] is ruined beyond usability!" + return + + if(T.species.flags & IS_SYNTHETIC) + user << "This creature does not have DNA!" + return + + if(T.species.flags & NO_SCAN) + user << "We do not know how to parse this creature's DNA!" + return + + if(has_dna(target.dna)) + user << "We already have this DNA in storage!" + + return 1 + diff --git a/code/game/gamemodes/changeling/changeling_power.dm b/code/game/gamemodes/changeling/changeling_power.dm new file mode 100644 index 00000000000..36df179ae32 --- /dev/null +++ b/code/game/gamemodes/changeling/changeling_power.dm @@ -0,0 +1,79 @@ +/* + * Don't use the apostrophe in name or desc. Causes script errors. + * TODO: combine atleast some of the functionality with /proc_holder/spell + */ + +/obj/effect/proc_holder/changeling + panel = "Changeling" + name = "Prototype Sting" + desc = "" // Fluff + var/helptext = "" // Details + var/chemical_cost = 0 // negative chemical cost is for passive abilities (chemical glands) + var/dna_cost = -1 //cost of the sting in dna points. 0 = auto-purchase, -1 = cannot be purchased + var/req_dna = 0 //amount of dna needed to use this ability. Changelings always have atleast 1 + var/req_human = 0 //if you need to be human to use this ability + var/req_stat = CONSCIOUS // CONSCIOUS, UNCONSCIOUS or DEAD + var/genetic_damage = 0 // genetic damage caused by using the sting. Nothing to do with cloneloss. + var/max_genetic_damage = 100 // hard counter for spamming abilities. Not used/balanced much yet. + +/obj/effect/proc_holder/changeling/proc/on_purchase(var/mob/user) + return + +/obj/effect/proc_holder/changeling/Click() + var/mob/user = usr + if(!user || !user.mind || !user.mind.changeling) + return + try_to_sting(user) + +/obj/effect/proc_holder/changeling/proc/try_to_sting(var/mob/user, var/mob/target) + if(!user.mind || !user.mind.changeling) + return + if(!can_sting(user, target)) + return + var/datum/changeling/c = user.mind.changeling + if(sting_action(user, target)) + sting_feedback(user, target) + take_chemical_cost(c) + +/obj/effect/proc_holder/changeling/proc/sting_action(var/mob/user, var/mob/target) + return 0 + +/obj/effect/proc_holder/changeling/proc/sting_feedback(var/mob/user, var/mob/target) + return 0 + +/obj/effect/proc_holder/changeling/proc/take_chemical_cost(var/datum/changeling/changeling) + changeling.chem_charges -= chemical_cost + changeling.geneticdamage += genetic_damage + +//Fairly important to remember to return 1 on success >.< +/obj/effect/proc_holder/changeling/proc/can_sting(var/mob/user, var/mob/target) + if(!ishuman(user) && !ismonkey(user)) //typecast everything from mob to carbon from this point onwards + return 0 + if(req_human && !ishuman(user)) + user << "We cannot do that in this form!" + return 0 + var/datum/changeling/c = user.mind.changeling + if(c.chem_chargesWe require at least [chemical_cost] unit\s of chemicals to do that!" + return 0 + if(c.absorbedcountWe require at least [req_dna] sample\s of compatible DNA." + return 0 + if(req_stat < user.stat) + user << "We are incapacitated." + return 0 + if((user.status_flags & FAKEDEATH) && name!="Regenerate") + user << "We are incapacitated." + return 0 + if(c.geneticdamage > max_genetic_damage) + user << "Our genomes are still reassembling. We need time to recover first." + return 0 + return 1 + +//used in /mob/Stat() +/obj/effect/proc_holder/changeling/proc/can_be_used_by(var/mob/user) + if(!ishuman(user) && !ismonkey(user)) + return 0 + if(req_human && !ishuman(user)) + return 0 + return 1 diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm deleted file mode 100644 index c6df778144d..00000000000 --- a/code/game/gamemodes/changeling/changeling_powers.dm +++ /dev/null @@ -1,944 +0,0 @@ -//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) - if(!ishuman(src) && !ismonkey(src)) return - verbs += /datum/changeling/proc/EvolutionMenu - - var/lesser_form = !ishuman(src) - - if(!powerinstances.len) - for(var/P in powers) - powerinstances += new P() - - // Code to auto-purchase free powers. - for(var/datum/power/changeling/P in powerinstances) - if(!P.genomecost) // Is it free? - if(!(P in mind.changeling.purchasedpowers)) // Do we not have it already? - mind.changeling.purchasePower(mind, P.name, 0)// Purchase it. Don't remake our verbs, we're doing it after this. - - for(var/datum/power/changeling/P in mind.changeling.purchasedpowers) - if(P.isVerb) - if(lesser_form && !P.allowduringlesserform) continue - if(!(P in src.verbs)) - 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 -/mob/proc/remove_changeling_powers() - if(!mind || !mind.changeling) return - for(var/datum/power/changeling/P in mind.changeling.purchasedpowers) - if(P.isVerb) - verbs -= P.verbpath - - -//Helper proc. Does all the checks and stuff for us to avoid copypasta -/mob/proc/changeling_power(var/required_chems=0, var/required_dna=0, var/max_genetic_damage=100, var/max_stat=0) - - if(!src.mind) return - if(!iscarbon(src)) return - - var/datum/changeling/changeling = src.mind.changeling - if(!changeling) - world.log << "[src] has the changeling_transform() verb but is not a changeling." - return - - if(src.stat > max_stat) - src << "We are incapacitated." - return - - if(changeling.absorbed_dna.len < required_dna) - src << "We require at least [required_dna] samples of compatible DNA." - return - - if(changeling.chem_charges < required_chems) - src << "We require at least [required_chems] units of chemicals to do that!" - return - - if(changeling.geneticdamage > max_genetic_damage) - src << "Our geneomes are still reassembling. We need time to recover first." - return - - 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 - H.set_species(S,null,1) //Until someone moves body colour into DNA, they're going to have to use the default. - - spawn(10) - src.verbs += /mob/proc/changeling_change_species - src.regenerate_icons() - - 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() - set category = "Changeling" - set name = "Absorb DNA" - - var/datum/changeling/changeling = changeling_power(0,0,100) - if(!changeling) return - - var/obj/item/weapon/grab/G = src.get_active_hand() - if(!istype(G)) - src << "We must be grabbing a creature in our active hand to absorb them." - return - - var/mob/living/carbon/human/T = G.affecting - if(!istype(T)) - 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((M_NOCLONE || SKELETON) in T.mutations) - src << "This creature's DNA is ruined beyond useability!" - return - - if(!G.state == GRAB_KILL) - src << "We must have a tighter grip to absorb this creature." - return - - if(changeling.isabsorbing) - src << "We are already absorbing!" - return - - changeling.isabsorbing = 1 - for(var/stage = 1, stage<=3, stage++) - switch(stage) - if(1) - src << "This creature is compatible. We must hold still..." - if(2) - src << "We extend a proboscis." - src.visible_message("[src] extends a proboscis!") - if(3) - src << "We stab [T] with the proboscis." - src.visible_message("[src] stabs [T] with the proboscis!") - T << "You feel a sharp stabbing pain!" - var/datum/organ/external/affecting = T.get_organ(src.zone_sel.selecting) - if(affecting.take_damage(39,0,1,0,"large organic needle")) - T:UpdateDamageIcon() - continue - - feedback_add_details("changeling_powers","A[stage]") - if(!do_mob(src, T, 150)) - src << "Our absorption of [T] has been interrupted!" - changeling.isabsorbing = 0 - return - - src << "We have absorbed [T]!" - src.visible_message("[src] sucks the fluids from [T]!") - T << "You have been absorbed by the changeling!" - - T.dna.real_name = T.real_name //Set this again, just to be sure that it's properly set. - changeling.absorbed_dna |= T.dna - if(src.nutrition < 400) src.nutrition = min((src.nutrition + T.nutrition), 400) - - 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 - if(dna_data in changeling.absorbed_dna) - continue - changeling.absorbed_dna += dna_data - changeling.absorbedcount++ - T.mind.changeling.absorbed_dna.len = 1 - - if(T.mind.changeling.purchasedpowers) - for(var/datum/power/changeling/Tp in T.mind.changeling.purchasedpowers) - if(Tp in changeling.purchasedpowers) - continue - else - changeling.purchasedpowers += Tp - - if(!Tp.isVerb) - call(Tp.verbpath)() - else - changeling.purchasedpowers += Tp - - if(!Tp.isVerb) - call(Tp.verbpath)() - else - src.make_changeling() - - changeling.chem_charges += T.mind.changeling.chem_charges - changeling.geneticpoints += T.mind.changeling.geneticpoints - T.mind.changeling.chem_charges = 0 - T.mind.changeling.geneticpoints = 0 - T.mind.changeling.absorbedcount = 0 - - changeling.absorbedcount++ - changeling.isabsorbing = 0 - - T.death(0) - T.Drain() - return 1 - - -//Change our DNA to that of somebody we've absorbed. -/mob/proc/changeling_transform() - set category = "Changeling" - set name = "Transform (5)" - - var/datum/changeling/changeling = changeling_power(5,1,0) - if(!changeling) return - - var/list/names = list() - for(var/datum/dna/DNA in changeling.absorbed_dna) - names += "[DNA.real_name]" - - var/S = input("Select the target DNA: ", "Target DNA", null) as null|anything in names - if(!S) return - - var/datum/dna/chosen_dna = changeling.GetDNA(S) - if(!chosen_dna) - return - - changeling.chem_charges -= 5 - src.visible_message("[src] transforms!") - changeling.geneticdamage = 30 - src.dna = chosen_dna.Clone() - src.real_name = chosen_dna.real_name - src.flavor_text = "" - if(ishuman(src)) - var/mob/living/carbon/human/H = src - H.set_species() - src.UpdateAppearance() - domutcheck(src, null) - - src.verbs -= /mob/proc/changeling_transform - spawn(10) src.verbs += /mob/proc/changeling_transform - - feedback_add_details("changeling_powers","TR") - return 1 - - -//Transform into a monkey. -/mob/proc/changeling_lesser_form() - set category = "Changeling" - set name = "Lesser Form (1)" - - var/datum/changeling/changeling = changeling_power(1,0,0) - if(!changeling) return - - if(src.has_brain_worms()) - src << "We cannot perform this ability at the present time!" - return - - var/mob/living/carbon/C = src - changeling.chem_charges-- - C.remove_changeling_powers() - C.visible_message("[C] transforms!") - changeling.geneticdamage = 30 - C << "Our genes cry out!" - - //TODO replace with monkeyize proc - var/list/implants = list() //Try to preserve implants. - for(var/obj/item/weapon/implant/W in C) - implants += W - - C.monkeyizing = 1 - C.canmove = 0 - C.icon = null - C.overlays.Cut() - C.invisibility = 101 - - var/atom/movable/overlay/animation = new /atom/movable/overlay( C.loc ) - animation.icon_state = "blank" - animation.icon = 'icons/mob/mob.dmi' - animation.master = src - flick("h2monkey", animation) - sleep(48) - del(animation) - - var/mob/living/carbon/monkey/O = new /mob/living/carbon/monkey(src) - O.dna = C.dna.Clone() - C.dna = null - - for(var/obj/item/W in C) - C.drop_from_inventory(W) - for(var/obj/T in C) - del(T) - - O.loc = C.loc - O.name = "monkey ([copytext(md5(C.real_name), 2, 6)])" - O.setToxLoss(C.getToxLoss()) - O.adjustBruteLoss(C.getBruteLoss()) - O.setOxyLoss(C.getOxyLoss()) - O.adjustFireLoss(C.getFireLoss()) - O.stat = C.stat - O.a_intent = "harm" - for(var/obj/item/weapon/implant/I in implants) - I.loc = O - I.implanted = O - - C.mind.transfer_to(O) - - 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 - - -//Transform into a human -/mob/proc/changeling_lesser_transform() - set category = "Changeling" - set name = "Transform (1)" - - var/datum/changeling/changeling = changeling_power(1,1,0) - if(!changeling) return - - var/list/names = list() - for(var/datum/dna/DNA in changeling.absorbed_dna) - names += "[DNA.real_name]" - - var/S = input("Select the target DNA: ", "Target DNA", null) as null|anything in names - if(!S) return - - var/datum/dna/chosen_dna = changeling.GetDNA(S) - if(!chosen_dna) - return - - var/mob/living/carbon/C = src - - changeling.chem_charges-- - C.remove_changeling_powers() - C.visible_message("[C] transforms!") - C.dna = chosen_dna.Clone() - - var/list/implants = list() - for (var/obj/item/weapon/implant/I in C) //Still preserving implants - implants += I - - C.monkeyizing = 1 - C.canmove = 0 - C.icon = null - C.overlays.Cut() - C.invisibility = 101 - var/atom/movable/overlay/animation = new /atom/movable/overlay( C.loc ) - animation.icon_state = "blank" - animation.icon = 'icons/mob/mob.dmi' - animation.master = src - flick("monkey2h", animation) - sleep(48) - del(animation) - - for(var/obj/item/W in src) - C.u_equip(W) - if (C.client) - C.client.screen -= W - if (W) - W.loc = C.loc - W.dropped(C) - W.layer = initial(W.layer) - - var/mob/living/carbon/human/O = new /mob/living/carbon/human( src, delay_ready_dna=1 ) - if (C.dna.GetUIState(DNA_UI_GENDER)) - O.gender = FEMALE - else - O.gender = MALE - O.dna = C.dna.Clone() - C.dna = null - O.real_name = chosen_dna.real_name - O.set_species() - for(var/obj/T in C) - del(T) - - O.loc = C.loc - - O.UpdateAppearance() - domutcheck(O, null) - O.setToxLoss(C.getToxLoss()) - O.adjustBruteLoss(C.getBruteLoss()) - O.setOxyLoss(C.getOxyLoss()) - O.adjustFireLoss(C.getFireLoss()) - O.stat = C.stat - for (var/obj/item/weapon/implant/I in implants) - I.loc = O - I.implanted = O - - C.mind.transfer_to(O) - O.make_changeling() - O.changeling_update_languages(changeling.absorbed_languages) - - feedback_add_details("changeling_powers","LFT") - del(C) - return 1 - - -//Fake our own death and fully heal. You will appear to be dead but regenerate fully after a short delay. -/* -/mob/verb/honk() - set name = "OH HOLY FUCK" - set category = "Debug" - var/yes = 0 - if(src in mob_list) - yes = 1 - else - var/mob/M = locate(src) in mob_list - if(M == src) - yes = 1 - usr << "[yes ? "\blue" : "\red"] You are [yes ? "" : "not "]in the mob list" -*/ -/mob/proc/changeling_returntolife() - set category = "Changeling" - set name = "Return To Life (20)" - var/datum/changeling/changeling = changeling_power(20,1,100,DEAD) - if(!changeling) return - - var/mob/living/carbon/C = src - if(changeling_power(20,1,100,DEAD)) - changeling.chem_charges -= 20 - dead_mob_list -= C - living_mob_list |= C - C.stat = CONSCIOUS - C.tod = null - C.setToxLoss(0) - C.setOxyLoss(0) - C.setCloneLoss(0) - C.setBrainLoss(0) - C.SetParalysis(0) - C.SetStunned(0) - C.SetWeakened(0) - C.radiation = 0 - C.heal_overall_damage(C.getBruteLoss(), C.getFireLoss()) - C.reagents.clear_reagents() - C.germ_level = 0 - C.next_pain_time = 0 - C.traumatic_shock = 0 - if(ishuman(C)) - var/mob/living/carbon/human/H = C - H.vessel.reagent_list = list() - H.vessel.add_reagent("blood",560) - H.shock_stage = 0 - spawn(1) - H.fixblood() - for(var/organ_name in H.organs_by_name) - var/datum/organ/external/O = H.organs_by_name[organ_name] - for(var/obj/item/weapon/shard/shrapnel/s in O.implants) - if(istype(s)) - O.implants -= s - H.contents -= s - del(s) - O.amputated = 0 - O.brute_dam = 0 - O.burn_dam = 0 - O.damage_state = "00" - O.germ_level = 0 - O.hidden = null - O.number_wounds = 0 - O.open = 0 - O.perma_injury = 0 - O.stage = 0 - O.status = 0 - O.trace_chemicals = list() - O.wounds = list() - O.wound_update_accuracy = 1 - for(var/n in H.internal_organs_by_name) - var/datum/organ/internal/IO = H.internal_organs_by_name[n] - IO.damage = 0 - IO.trace_chemicals = list() - H.updatehealth() - C << "We have regenerated." - C.visible_message("[src] appears to wake from the dead, having healed all wounds.") - C.status_flags &= ~(FAKEDEATH) - C.update_canmove() - C.make_changeling() - src.verbs -= /mob/proc/changeling_returntolife - feedback_add_details("changeling_powers","RJ") - -/mob/proc/changeling_fakedeath() - set category = "Changeling" - set name = "Regenerative Stasis (20)" - - var/datum/changeling/changeling = changeling_power(20,1,100,DEAD) - if(!changeling) return - - var/mob/living/carbon/C = src - if(!C.stat && alert("Are we sure we wish to fake our death?",,"Yes","No") == "No")//Confirmation for living changelings if they want to fake their death - return - C << "We will attempt to regenerate our form." - - C.status_flags |= FAKEDEATH //play dead - C.update_canmove() - C.remove_changeling_powers() - - C.emote("deathgasp") - C.tod = worldtime2text() - - spawn(rand(800,1200)) - src << "We are now ready to regenerate." - src.verbs += /mob/proc/changeling_returntolife - feedback_add_details("changeling_powers","FD") - return 1 - - -//Boosts the range of your next sting attack by 1 -/mob/proc/changeling_boost_range() - set category = "Changeling" - set name = "Ranged Sting (10)" - set desc="Your next sting ability can be used against targets 2 squares away." - - var/datum/changeling/changeling = changeling_power(10,0,100) - if(!changeling) return 0 - changeling.chem_charges -= 10 - src << "Your throat adjusts to launch the sting." - changeling.sting_range = 2 - src.verbs -= /mob/proc/changeling_boost_range - spawn(5) src.verbs += /mob/proc/changeling_boost_range - feedback_add_details("changeling_powers","RS") - return 1 - - -//Recover from stuns. -/mob/proc/changeling_unstun() - set category = "Changeling" - set name = "Epinephrine Sacs (45)" - set desc = "Removes all stuns" - - var/datum/changeling/changeling = changeling_power(45,0,100,UNCONSCIOUS) - if(!changeling) return 0 - changeling.chem_charges -= 45 - - var/mob/living/carbon/human/C = src - C.stat = 0 - C.SetParalysis(0) - C.SetStunned(0) - C.SetWeakened(0) - C.adjustStaminaLoss(-75) - C.reagents.add_reagent("synaptizine", 20) - C.lying = 0 - C.update_canmove() - - src.verbs -= /mob/proc/changeling_unstun - spawn(5) src.verbs += /mob/proc/changeling_unstun - feedback_add_details("changeling_powers","UNS") - return 1 - - -//Speeds up chemical regeneration -/mob/proc/changeling_fastchemical() - src.mind.changeling.chem_recharge_rate *= 2 - return 1 - -//Increases macimum chemical storage -/mob/proc/changeling_engorgedglands() - src.mind.changeling.chem_storage += 25 - return 1 - - -//Prevents AIs tracking you but makes you easily detectable to the human-eye. -/mob/proc/changeling_digitalcamo() - set category = "Changeling" - set name = "Toggle Digital Camoflague" - set desc = "The AI can no longer track us, but we will look different if examined. Has a constant cost while active." - - var/datum/changeling/changeling = changeling_power() - if(!changeling) return 0 - - var/mob/living/carbon/human/C = src - if(C.digitalcamo) C << "We return to normal." - else C << "We distort our form to prevent AI-tracking." - C.digitalcamo = !C.digitalcamo - - spawn(0) - while(C && C.digitalcamo && C.mind && C.mind.changeling) - C.mind.changeling.chem_charges = max(C.mind.changeling.chem_charges - 1, 0) - sleep(40) - - src.verbs -= /mob/proc/changeling_digitalcamo - spawn(5) src.verbs += /mob/proc/changeling_digitalcamo - feedback_add_details("changeling_powers","CAM") - return 1 - - -//Starts healing you every second for 10 seconds. Can be used whilst unconscious. -/mob/proc/changeling_rapidregen() - set category = "Changeling" - set name = "Rapid Regeneration (30)" - set desc = "Begins rapidly regenerating. Does not effect stuns or chemicals." - - var/datum/changeling/changeling = changeling_power(30,0,100,UNCONSCIOUS) - if(!changeling) return 0 - src.mind.changeling.chem_charges -= 30 - - var/mob/living/carbon/human/C = src - if(ishuman(src)) - var/mob/living/carbon/human/H=src - if(H.said_last_words) - H.said_last_words=0 - - spawn(0) - for(var/i = 0, i<10,i++) - if(C) - C.adjustBruteLoss(-10) - C.adjustToxLoss(-10) - C.adjustOxyLoss(-10) - C.adjustFireLoss(-10) - sleep(10) - - src.verbs -= /mob/proc/changeling_rapidregen - spawn(5) src.verbs += /mob/proc/changeling_rapidregen - feedback_add_details("changeling_powers","RR") - return 1 - -// HIVE MIND UPLOAD/DOWNLOAD DNA - -var/list/datum/dna/hivemind_bank = list() - -/mob/proc/changeling_hiveupload() - set category = "Changeling" - set name = "Hive Channel (10)" - set desc = "Allows you to channel DNA in the airwaves to allow other changelings to absorb it." - - var/datum/changeling/changeling = changeling_power(10,1) - if(!changeling) return - - var/list/names = list() - for(var/datum/dna/DNA in changeling.absorbed_dna) - if(!(DNA in hivemind_bank)) - names += DNA.real_name - - if(names.len <= 0) - src << "The airwaves already have all of our DNA." - return - - var/S = input("Select a DNA to channel: ", "Channel DNA", null) as null|anything in names - if(!S) return - - var/datum/dna/chosen_dna = changeling.GetDNA(S) - if(!chosen_dna) - return - - changeling.chem_charges -= 10 - hivemind_bank += chosen_dna - src << "We channel the DNA of [S] to the air." - feedback_add_details("changeling_powers","HU") - return 1 - -/mob/proc/changeling_hivedownload() - set category = "Changeling" - set name = "Hive Absorb (20)" - set desc = "Allows you to absorb DNA that is being channelled in the airwaves." - - var/datum/changeling/changeling = changeling_power(20,1) - if(!changeling) return - - var/list/names = list() - for(var/datum/dna/DNA in hivemind_bank) - if(!(DNA in changeling.absorbed_dna)) - names[DNA.real_name] = DNA - - if(names.len <= 0) - src << "There's no new DNA to absorb from the air." - return - - var/S = input("Select a DNA absorb from the air: ", "Absorb DNA", null) as null|anything in names - if(!S) return - var/datum/dna/chosen_dna = names[S] - if(!chosen_dna) - return - - changeling.chem_charges -= 20 - changeling.absorbed_dna += chosen_dna - src << "We absorb the DNA of [S] from the air." - feedback_add_details("changeling_powers","HD") - return 1 - -// Fake Voice - -/mob/proc/changeling_mimicvoice() - set category = "Changeling" - set name = "Mimic Voice" - set desc = "Shape our vocal glands to form a voice of someone we choose. We cannot regenerate chemicals when mimicing." - - - var/datum/changeling/changeling = changeling_power() - if(!changeling) return - - if(changeling.mimicing) - changeling.mimicing = "" - src << "We return our vocal glands to their original location." - return - - var/mimic_voice = stripped_input(usr, "Enter a name to mimic.", "Mimic Voice", null, MAX_NAME_LEN) - if(!mimic_voice) - return - - changeling.mimicing = mimic_voice - - src << "We shape our glands to take the voice of [mimic_voice], this will stop us from regenerating chemicals while active." - src << "Use this power again to return to our original voice and reproduce chemicals again." - - feedback_add_details("changeling_powers","MV") - - spawn(0) - while(src && src.mind && src.mind.changeling && src.mind.changeling.mimicing) - src.mind.changeling.chem_charges = max(src.mind.changeling.chem_charges - 1, 0) - sleep(40) - if(src && src.mind && src.mind.changeling) - src.mind.changeling.mimicing = "" - ////////// - //STINGS// //They get a pretty header because there's just so fucking many of them ;_; - ////////// - -/mob/proc/sting_can_reach(mob/M as mob, sting_range = 1) - if(M.loc == src.loc) return 1 //target and source are in the same thing - if(!isturf(src.loc) || !isturf(M.loc)) return 0 //One is inside, the other is outside something. - if(AStar(src.loc, M.loc, /turf/proc/AdjacentTurfs, /turf/proc/Distance, sting_range)) //If a path exists, good! - return 1 - return 0 - -//Handles the general sting code to reduce on copypasta (seeming as somebody decided to make SO MANY dumb abilities) -/mob/proc/changeling_sting(var/required_chems=0, var/verb_path) - var/datum/changeling/changeling = changeling_power(required_chems) - if(!changeling) return - - var/list/victims = list() - for(var/mob/living/carbon/C in oview(changeling.sting_range)) - victims += C - var/mob/living/carbon/T = input(src, "Who will we sting?") as null|anything in victims - - if(!T) return - if(!(T in view(changeling.sting_range))) return - if(!sting_can_reach(T, changeling.sting_range)) return - if(!changeling_power(required_chems)) return - - if(ishuman(T)) - var/mob/living/carbon/human/H = T - if(H.species.flags & IS_SYNTHETIC) - src << "This won't work on synthetics." - return - - changeling.chem_charges -= required_chems - changeling.sting_range = 1 - src.verbs -= verb_path - spawn(10) src.verbs += verb_path - - src << "We stealthily sting [T]." - if(!T.mind || !T.mind.changeling) return T //T will be affected by the sting - T << "You feel a tiny prick." - return - - -/mob/proc/changeling_lsdsting() - set category = "Changeling" - set name = "Hallucination Sting (15)" - set desc = "Causes terror in the target." - - var/mob/living/carbon/T = changeling_sting(15,/mob/proc/changeling_lsdsting) - if(!T) return 0 - spawn(rand(300,600)) - if(T) T.hallucination += 400 - feedback_add_details("changeling_powers","HS") - return 1 - -/mob/proc/changeling_silence_sting() - set category = "Changeling" - set name = "Silence sting (10)" - set desc="Sting target" - - var/mob/living/carbon/T = changeling_sting(10,/mob/proc/changeling_silence_sting) - if(!T) return 0 - T.silent += 30 - feedback_add_details("changeling_powers","SS") - return 1 - -/mob/proc/changeling_blind_sting() - set category = "Changeling" - set name = "Blind sting (20)" - set desc="Sting target" - - var/mob/living/carbon/T = changeling_sting(20,/mob/proc/changeling_blind_sting) - if(!T) return 0 - T << "Your eyes burn horrificly!" - T.disabilities |= NEARSIGHTED - spawn(300) T.disabilities &= ~NEARSIGHTED - T.eye_blind = 10 - T.eye_blurry = 20 - feedback_add_details("changeling_powers","BS") - return 1 - -/mob/proc/changeling_deaf_sting() - set category = "Changeling" - set name = "Deaf sting (5)" - set desc="Sting target:" - - var/mob/living/carbon/T = changeling_sting(5,/mob/proc/changeling_deaf_sting) - if(!T) return 0 - T << "Your ears pop and begin ringing loudly!" - T.sdisabilities |= DEAF - spawn(300) T.sdisabilities &= ~DEAF - feedback_add_details("changeling_powers","DS") - return 1 - -/mob/proc/changeling_paralysis_sting() - set category = "Changeling" - set name = "Paralysis sting (30)" - set desc="Sting target" - - var/mob/living/carbon/T = changeling_sting(30,/mob/proc/changeling_paralysis_sting) - if(!T) return 0 - T << "Your muscles begin to painfully tighten." - T.Weaken(20) - feedback_add_details("changeling_powers","PS") - return 1 - -/mob/proc/changeling_transformation_sting() - set category = "Changeling" - set name = "Transformation sting (40)" - set desc="Sting target" - - var/datum/changeling/changeling = changeling_power(40) - if(!changeling) return 0 - - - - var/list/names = list() - for(var/datum/dna/DNA in changeling.absorbed_dna) - names += "[DNA.real_name]" - - var/S = input("Select the target DNA: ", "Target DNA", null) as null|anything in names - if(!S) return - - var/datum/dna/chosen_dna = changeling.GetDNA(S) - if(!chosen_dna) - return - - var/mob/living/carbon/T = changeling_sting(40,/mob/proc/changeling_transformation_sting) - if(!T) return 0 - if((M_HUSK in T.mutations) || (!ishuman(T) && !ismonkey(T))) - src << "Our sting appears ineffective against its DNA." - return 0 - T.visible_message("[T] transforms!") - T.dna = chosen_dna.Clone() - T.real_name = chosen_dna.real_name - T.UpdateAppearance() - domutcheck(T, null) - feedback_add_details("changeling_powers","TS") - return 1 - -/mob/proc/changeling_unfat_sting() - set category = "Changeling" - set name = "Unfat sting (5)" - set desc = "Sting target" - - var/mob/living/carbon/T = changeling_sting(5,/mob/proc/changeling_unfat_sting) - if(!T) return 0 - T << "You feel a small prick as stomach churns violently and you become to feel skinnier." - T.overeatduration = 0 - T.nutrition -= 100 - feedback_add_details("changeling_powers","US") - return 1 - -/mob/proc/changeling_DEATHsting() - set category = "Changeling" - set name = "Death Sting (40)" - set desc = "Causes spasms onto death." - - var/mob/living/carbon/T = changeling_sting(40,/mob/proc/changeling_DEATHsting) - if(!T) return 0 - T << "You feel a small prick and your chest becomes tight." - T.silent = 10 - T.Paralyse(10) - T.Jitter(1000) - if(T.reagents) T.reagents.add_reagent("lexorin", 40) - feedback_add_details("changeling_powers","DTHS") - return 1 - -/mob/proc/changeling_extract_dna_sting() - set category = "Changeling" - set name = "Extract DNA Sting (40)" - set desc="Stealthily sting a target to extract their DNA." - - var/datum/changeling/changeling = null - if(src.mind && src.mind.changeling) - changeling = src.mind.changeling - if(!changeling) - return 0 - - var/mob/living/carbon/human/T = changeling_sting(40, /mob/proc/changeling_extract_dna_sting) - if(!T) return 0 - if(T.species.flags & NO_SCAN) // Yeah, this needs the same protection, otherwise you can steal DNA from Slime People and then blood overdose when you turn into one. - src << "We do not know how to parse this creature's DNA!" - changeling.chem_charges += 40 - return 0 - - T.dna.real_name = T.real_name - changeling.absorbed_dna |= T.dna - if(T.species && !(T.species.name in changeling.absorbed_species)) - changeling.absorbed_species += T.species.name - - feedback_add_details("changeling_powers","ED") - return 1 diff --git a/code/game/gamemodes/changeling/evolution_menu.dm b/code/game/gamemodes/changeling/evolution_menu.dm new file mode 100644 index 00000000000..32ab8473d66 --- /dev/null +++ b/code/game/gamemodes/changeling/evolution_menu.dm @@ -0,0 +1,416 @@ +var/list/sting_paths +// totally stolen from the new player panel. YAYY + +/obj/effect/proc_holder/changeling/evolution_menu + name = "-Evolution Menu-" //Dashes are so it's listed before all the other abilities. + desc = "Choose our method of subjugation." + dna_cost = 0 + +/obj/effect/proc_holder/changeling/evolution_menu/Click() + if(!usr || !usr.mind || !usr.mind.changeling) + return + var/datum/changeling/changeling = usr.mind.changeling + + if(!sting_paths) + sting_paths = init_subtypes(/obj/effect/proc_holder/changeling) + + var/dat = create_menu(changeling) + usr << browse(dat, "window=powers;size=600x700")//900x480 + + +/obj/effect/proc_holder/changeling/evolution_menu/proc/create_menu(var/datum/changeling/changeling) + var/dat + dat +="Changling Evolution Menu" + + //javascript, the part that does most of the work~ + dat += {" + + + + + + + "} + + //body tag start + onload and onkeypress (onkeyup) javascript event calls + dat += "" + + //title + search bar + dat += {" + + + + + + + + +
+ Changeling Evolution Menu
+ Hover over a power to see more information
+ Current ability choices remaining: [changeling.geneticpoints]
+ By rendering a lifeform to a husk, we gain enough power to alter and adapt our evolutions.
+ (Readapt)
+

+

+ Search: +
+ + "} + + //player table header + dat += {" + + "} + + var/i = 1 + for(var/obj/effect/proc_holder/changeling/cling_power in sting_paths) + + if(cling_power.dna_cost <= 0) //Let's skip the crap we start with. Keeps the evolution menu uncluttered. + continue + + var/ownsthis = changeling.has_sting(cling_power) + + var/color + if(ownsthis) + if(i%2 == 0) + color = "#d8ebd8" + else + color = "#c3dec3" + else + if(i%2 == 0) + color = "#f2f2f2" + else + color = "#e6e6e6" + + + dat += {" + + + + + + "} + + i++ + + + //player table ending + dat += {" +
+ + + Evolve [cling_power][ownsthis ? " - Purchased" : (cling_power.req_dna>changeling.absorbedcount ? " - Requires [cling_power.req_dna] absorptions" : " - Cost: [cling_power.dna_cost]")] + +
+
+
+ + + + "} + return dat + + +/obj/effect/proc_holder/changeling/evolution_menu/Topic(href, href_list) + ..() + if(!(iscarbon(usr) && usr.mind && usr.mind.changeling)) + return + + if(href_list["P"]) + usr.mind.changeling.purchasePower(usr, href_list["P"]) + else if(href_list["readapt"]) + usr.mind.changeling.lingRespec(usr) + var/dat = create_menu(usr.mind.changeling) + usr << browse(dat, "window=powers;size=600x700") +///// + +/datum/changeling/proc/purchasePower(var/mob/living/carbon/user, var/sting_name) + + var/obj/effect/proc_holder/changeling/thepower = null + + if(!sting_paths) + sting_paths = init_subtypes(/obj/effect/proc_holder/changeling) + for(var/obj/effect/proc_holder/changeling/cling_sting in sting_paths) + if(cling_sting.name == sting_name) + thepower = cling_sting + + if(thepower == null) + user << "This is awkward. Changeling power purchase failed, please report this bug to a coder!" + return + + if(absorbedcount < thepower.req_dna) + user << "We lack the energy to evolve this ability!" + return + + if(has_sting(thepower)) + user << "We have already evolved this ability!" + return + + if(thepower.dna_cost < 0) + user << "We cannot evolve this ability." + return + + if(geneticpoints < thepower.dna_cost) + user << "We have reached our capacity for abilities." + return + + if(user.status_flags & FAKEDEATH)//To avoid potential exploits by buying new powers while in stasis, which clears your verblist. + user << "We lack the energy to evolve new abilities right now." + return + + geneticpoints -= thepower.dna_cost + purchasedpowers += thepower + thepower.on_purchase(user) + +//Reselect powers +/datum/changeling/proc/lingRespec(var/mob/user) + if(!ishuman(user)) + user << "We can't remove our evolutions in this form!" + return + if(canrespec) + user << "We have removed our evolutions from this form, and are now ready to readapt." + user.remove_changeling_powers(1) + canrespec = 0 + user.make_changeling() + return 1 + else + user << "You lack the power to readapt your evolutions!" + return 0 + +/mob/proc/make_changeling() + if(!mind) + return + if(!ishuman(src) && !ismonkey(src)) + return + if(!mind.changeling) + mind.changeling = new /datum/changeling(gender) + if(!sting_paths) + sting_paths = init_subtypes(/obj/effect/proc_holder/changeling) + if(mind.changeling.purchasedpowers) + remove_changeling_powers(1) + + add_language("Changeling") + + for(var/language in languages) + mind.changeling.absorbed_languages |= language + + // purchase free powers. + for(var/obj/effect/proc_holder/changeling/path in sting_paths) + //var/obj/effect/proc_holder/changeling/S = new path() + if(!path.dna_cost) + if(!mind.changeling.has_sting(path)) + mind.changeling.purchasedpowers += path + path.on_purchase(src) + + var/mob/living/carbon/C = src //only carbons have dna now, so we have to typecaste + mind.changeling.absorbed_dna |= C.dna + return 1 + +//Used to dump the languages from the changeling datum into the actual mob. +/mob/proc/changeling_update_languages(var/updated_languages) + + for(var/datum/language/L in updated_languages) + add_language("L.name") + + //This isn't strictly necessary but just to be safe... + add_language("Changeling") + + return + +/datum/changeling/proc/reset() + chosen_sting = null + geneticpoints = initial(geneticpoints) + sting_range = initial(sting_range) + chem_storage = initial(chem_storage) + chem_recharge_rate = initial(chem_recharge_rate) + chem_charges = min(chem_charges, chem_storage) + chem_recharge_slowdown = initial(chem_recharge_slowdown) + mimicing = "" + +/mob/proc/remove_changeling_powers(var/keep_free_powers=0) + if(ishuman(src) || ismonkey(src)) + if(mind && mind.changeling) + digitalcamo = 0 + mind.changeling.changeling_speak = 0 + mind.changeling.reset() + for(var/obj/effect/proc_holder/changeling/p in mind.changeling.purchasedpowers) + if(!(p.dna_cost == 0 && keep_free_powers)) + mind.changeling.purchasedpowers -= p + +/datum/changeling/proc/has_sting(obj/effect/proc_holder/changeling/power) + for(var/obj/effect/proc_holder/changeling/P in purchasedpowers) + if(power.name == P.name) + return 1 + return 0 diff --git a/code/game/gamemodes/changeling/modularchangling.dm b/code/game/gamemodes/changeling/modularchangling.dm deleted file mode 100644 index 68458760855..00000000000 --- a/code/game/gamemodes/changeling/modularchangling.dm +++ /dev/null @@ -1,506 +0,0 @@ -// READ: Don't use the apostrophe in name or desc. Causes script errors. - -var/list/powers = typesof(/datum/power/changeling) - /datum/power/changeling //needed for the badmin verb for now -var/list/datum/power/changeling/powerinstances = list() - -/datum/power //Could be used by other antags too - var/name = "Power" - var/desc = "Placeholder" - var/helptext = "" - var/isVerb = 1 // Is it an active power, or passive? - var/verbpath // Path to a verb that contains the effects. - -/datum/power/changeling - var/allowduringlesserform = 0 - var/genomecost = 500000 // Cost for the changling to evolve this power. - -/datum/power/changeling/absorb_dna - name = "Absorb DNA" - desc = "Permits us to syphon the DNA from a human. They become one with us, and we become stronger." - genomecost = 0 - verbpath = /mob/proc/changeling_absorb_dna - -/datum/power/changeling/transform - name = "Transform" - desc = "We take on the apperance and voice of one we have absorbed." - 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." - helptext = "Can be used before or after death. Duration varies greatly." - genomecost = 0 - allowduringlesserform = 1 - verbpath = /mob/proc/changeling_fakedeath - -// Hivemind - -/datum/power/changeling/hive_upload - name = "Hive Channel" - desc = "We can channel a DNA into the airwaves, allowing our fellow changelings to absorb it and transform into it as if they acquired the DNA themselves." - helptext = "Allows other changelings to absorb the DNA you channel from the airwaves. Will not help them towards their absorb objectives." - genomecost = 0 - verbpath = /mob/proc/changeling_hiveupload - -/datum/power/changeling/hive_download - name = "Hive Absorb" - desc = "We can absorb a single DNA from the airwaves, allowing us to use more disguises with help from our fellow changelings." - helptext = "Allows you to absorb a single DNA and use it. Does not count towards your absorb objective." - genomecost = 0 - verbpath = /mob/proc/changeling_hivedownload - -/datum/power/changeling/lesser_form - name = "Lesser Form" - desc = "We debase ourselves and become lesser. We become a monkey." - genomecost = 1 - verbpath = /mob/proc/changeling_lesser_form - -/datum/power/changeling/deaf_sting - name = "Deaf Sting" - desc = "We silently sting a human, completely deafening them for a short time." - genomecost = 1 - allowduringlesserform = 1 - verbpath = /mob/proc/changeling_deaf_sting - -/datum/power/changeling/blind_sting - name = "Blind Sting" - desc = "We silently sting a human, completely blinding them for a short time." - genomecost = 2 - allowduringlesserform = 1 - verbpath = /mob/proc/changeling_blind_sting - -/datum/power/changeling/silence_sting - 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 = 3 - allowduringlesserform = 1 - verbpath = /mob/proc/changeling_silence_sting - -/datum/power/changeling/mimicvoice - 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 - 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 - allowduringlesserform = 1 - verbpath = /mob/proc/changeling_extract_dna_sting - -/datum/power/changeling/transformation_sting - name = "Transformation Sting" - desc = "We silently sting a human, injecting a retrovirus that forces them to transform into another." - helptext = "Does not provide a warning to others. The victim will transform much like a changeling would." - genomecost = 3 - verbpath = /mob/proc/changeling_transformation_sting - -/datum/power/changeling/paralysis_sting - name = "Paralysis Sting" - desc = "We silently sting a human, paralyzing them for a short time." - genomecost = 4 - verbpath = /mob/proc/changeling_paralysis_sting - -/datum/power/changeling/LSDSting - name = "Hallucination Sting" - desc = "We evolve the ability to sting a target with a powerful hallunicationary chemical." - helptext = "The target does not notice they have been stung. The effect occurs after 30 to 60 seconds." - genomecost = 3 - verbpath = /mob/proc/changeling_lsdsting - -/datum/power/changeling/DeathSting - name = "Death Sting" - desc = "We silently sting a human, filling him with potent chemicals. His rapid death is all but assured." - genomecost = 10 - verbpath = /mob/proc/changeling_DEATHsting - -/datum/power/changeling/unfat_sting - name = "Unfat Sting" - desc = "We silently sting a human, forcing them to rapidly metobolize their fat." - genomecost = 1 - verbpath = /mob/proc/changeling_unfat_sting - -/datum/power/changeling/boost_range - name = "Boost Range" - desc = "We evolve the ability to shoot our stingers at humans, with some preperation." - genomecost = 2 - allowduringlesserform = 1 - verbpath = /mob/proc/changeling_boost_range - -/datum/power/changeling/Epinephrine - 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 - verbpath = /mob/proc/changeling_unstun - -/datum/power/changeling/ChemicalSynth - name = "Rapid Chemical-Synthesis" - desc = "We evolve new pathways for producing our necessary chemicals, permitting us to naturally create them faster." - helptext = "Doubles the rate at which we naturally recharge chemicals." - genomecost = 4 - isVerb = 0 - verbpath = /mob/proc/changeling_fastchemical -/* -/datum/power/changeling/AdvChemicalSynth - name = "Advanced Chemical-Synthesis" - desc = "We evolve new pathways for producing our necessary chemicals, permitting us to naturally create them faster." - helptext = "Doubles the rate at which we naturally recharge chemicals." - genomecost = 8 - isVerb = 0 - verbpath = /mob/proc/changeling_fastchemical -*/ -/datum/power/changeling/EngorgedGlands - name = "Engorged Chemical Glands" - desc = "Our chemical glands swell, permitting us to store more chemicals inside of them." - helptext = "Allows us to store an extra 25 units of chemicals." - genomecost = 4 - isVerb = 0 - verbpath = /mob/proc/changeling_engorgedglands - -/datum/power/changeling/DigitalCamoflague - 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 - allowduringlesserform = 1 - verbpath = /mob/proc/changeling_digitalcamo - -/datum/power/changeling/rapidregeneration - 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 - verbpath = /mob/proc/changeling_rapidregen - - - -// Modularchangling, totally stolen from the new player panel. YAYY -/datum/changeling/proc/EvolutionMenu()//The new one - set category = "Changeling" - set desc = "Level up!" - - if(!usr || !usr.mind || !usr.mind.changeling) return - src = usr.mind.changeling - - if(!powerinstances.len) - for(var/P in powers) - powerinstances += new P() - - var/dat = "Changling Evolution Menu" - - //javascript, the part that does most of the work~ - dat += {" - - - - - - - "} - - //body tag start + onload and onkeypress (onkeyup) javascript event calls - dat += "" - - //title + search bar - dat += {" - - - - - - - - -
- Changling Evolution Menu
- Hover over a power to see more information
- Current evolution points left to evolve with: [geneticpoints]
- Absorb genomes to acquire more evolution points -

-

- Search: -
- - "} - - //player table header - dat += {" - - "} - - var/i = 1 - for(var/datum/power/changeling/P in powerinstances) - var/ownsthis = 0 - - if(P in purchasedpowers) - ownsthis = 1 - - - var/color = "#e6e6e6" - if(i%2 == 0) - color = "#f2f2f2" - - - dat += {" - - - - - - "} - - i++ - - - //player table ending - dat += {" -
- - - Evolve [P] - Cost: [ownsthis ? "Purchased" : P.genomecost] - -
-
-
- - - - "} - - usr << browse(dat, "window=powers;size=900x480") - - -/datum/changeling/Topic(href, href_list) - ..() - if(!ismob(usr)) - return - - if(href_list["P"]) - var/datum/mind/M = usr.mind - if(!istype(M)) - return - purchasePower(M, href_list["P"]) - call(/datum/changeling/proc/EvolutionMenu)() - - - -/datum/changeling/proc/purchasePower(var/datum/mind/M, var/Pname, var/remake_verbs = 1) - if(!M || !M.changeling) - return - - var/datum/power/changeling/Thepower = Pname - - - for (var/datum/power/changeling/P in powerinstances) - //world << "[P] - [Pname] = [P.name == Pname ? "True" : "False"]" - if(P.name == Pname) - Thepower = P - break - - - if(Thepower == null) - M.current << "This is awkward. Changeling power purchase failed, please report this bug to a coder!" - return - - if(Thepower in purchasedpowers) - M.current << "We have already evolved this ability!" - return - - - if(geneticpoints < Thepower.genomecost) - M.current << "We cannot evolve this... yet. We must acquire more DNA." - return - - geneticpoints -= Thepower.genomecost - - purchasedpowers += Thepower - - if(!Thepower.isVerb && Thepower.verbpath) - call(M.current, Thepower.verbpath)() - else if(remake_verbs) - M.current.make_changeling() - diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm new file mode 100644 index 00000000000..115a5ae59d2 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/absorb.dm @@ -0,0 +1,107 @@ +/obj/effect/proc_holder/changeling/absorbDNA + name = "Absorb DNA" + desc = "Absorb the DNA of our victim." + chemical_cost = 0 + dna_cost = 0 + req_human = 1 + max_genetic_damage = 100 + +/obj/effect/proc_holder/changeling/absorbDNA/can_sting(var/mob/living/carbon/user) + if(!..()) + return + + var/datum/changeling/changeling = user.mind.changeling + if(changeling.isabsorbing) + user << "We are already absorbing!" + return + + var/obj/item/weapon/grab/G = user.get_active_hand() + if(!istype(G)) + user << "We must be grabbing a creature in our active hand to absorb them." + return + if(G.state <= GRAB_NECK) + user << "We must have a tighter grip to absorb this creature." + return + + var/mob/living/carbon/target = G.affecting + return changeling.can_absorb_dna(user,target) + + + +/obj/effect/proc_holder/changeling/absorbDNA/sting_action(var/mob/user) + var/datum/changeling/changeling = user.mind.changeling + var/obj/item/weapon/grab/G = user.get_active_hand() + var/mob/living/carbon/human/target = G.affecting + changeling.isabsorbing = 1 + for(var/stage = 1, stage<=3, stage++) + switch(stage) + if(1) + user << "This creature is compatible. We must hold still..." + if(2) + user << "We extend a proboscis." + user.visible_message("[user] extends a proboscis!") + if(3) + user << "We stab [target] with the proboscis." + user.visible_message("[user] stabs [target] with the proboscis!") + target << "You feel a sharp stabbing pain!" + target.take_overall_damage(40) + feedback_add_details("changeling_powers","A[stage]") + if(!do_mob(user, target, 150)) + user << "Our absorption of [target] has been interrupted!" + changeling.isabsorbing = 0 + return + + user << "We have absorbed [target]!" + user.visible_message("[user] sucks the fluids from [target]!") + target << "You have been absorbed by the changeling!" + + if(!changeling.has_dna(target.dna)) + changeling.absorb_dna(target, user) + + if(user.nutrition < 450) // Nutrition level before overeat_duration starts ticking for you to become obese. + user.nutrition = min((user.nutrition + target.nutrition), 450) + + if(target.mind)//if the victim has got a mind + + target.mind.show_memory(src, 0) //I can read your mind, kekeke. Output all their notes. + + if(target.mind.changeling)//If the target was a changeling, suck out their extra juice and objective points! + changeling.chem_charges += min(target.mind.changeling.chem_charges, changeling.chem_storage) + changeling.absorbedcount += (target.mind.changeling.absorbedcount) + + target.mind.changeling.absorbed_dna.len = 1 + target.mind.changeling.absorbedcount = 0 + + + changeling.chem_charges=min(changeling.chem_charges+10, changeling.chem_storage) + + changeling.isabsorbing = 0 + changeling.canrespec = 1 + + target.death(0) + target.Drain() + return 1 + + + +//Absorbs the target DNA. +/datum/changeling/proc/absorb_dna(mob/living/carbon/T, var/mob/user) + if(absorbed_dna.len) + absorbed_dna.Cut(1,2) + T.dna.real_name = T.real_name //Set this again, just to be sure that it's properly set. + var/datum/dna/new_dna = T.dna.Clone() + //Steal all of their languages! + for(var/language in T.languages) + if(!(language in absorbed_languages)) + absorbed_languages += language + user.changeling_update_languages(absorbed_languages) + + absorbedcount++ + store_dna(new_dna, user) + +/datum/changeling/proc/store_dna(var/datum/dna/new_dna, var/mob/user) + for(var/datum/objective/escape/escape_with_identity/E in user.mind.objectives) + if(E.target_real_name == new_dna.real_name) + protected_dna |= new_dna + return + absorbed_dna |= new_dna diff --git a/code/game/gamemodes/changeling/powers/augmented_eyesight.dm b/code/game/gamemodes/changeling/powers/augmented_eyesight.dm new file mode 100644 index 00000000000..d40da71fff1 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/augmented_eyesight.dm @@ -0,0 +1,24 @@ +//Augmented Eyesight: Gives you thermal and night vision - bye bye, flashlights. Also, high DNA cost because of how powerful it is. +//Possible todo: make a custom message for directing a penlight/flashlight at the eyes - not sure what would display though. + +/obj/effect/proc_holder/changeling/augmented_eyesight + name = "Augmented Eyesight" + desc = "Creates heat receptors in our eyes and dramatically increases light sensing ability." + helptext = "Grants us night vision and thermal vision. It may be toggled on or off." + chemical_cost = 0 + dna_cost = 2 //Would be 1 without thermal vision + var/active = 0 //Whether or not vision is enhanced + +/obj/effect/proc_holder/changeling/augmented_eyesight/sting_action(var/mob/user) + active = !active + if(active) + user << "We feel a minute twitch in our eyes, and darkness creeps away." + else + user << "Our vision dulls. Shadows gather." + user.sight &= ~SEE_MOBS + while(active) + user.see_in_dark = 8 + user.see_invisible = 2 + user.sight |= SEE_MOBS + sleep(1) //BAD THINGS HAPPEN WITHOUT THIS. + return 1 diff --git a/code/game/gamemodes/changeling/powers/digitalcamo.dm b/code/game/gamemodes/changeling/powers/digitalcamo.dm new file mode 100644 index 00000000000..92ae8e7781e --- /dev/null +++ b/code/game/gamemodes/changeling/powers/digitalcamo.dm @@ -0,0 +1,17 @@ +/obj/effect/proc_holder/changeling/digitalcamo + name = "Digital Camouflage" + desc = "By evolving the ability to distort our form and proprotions, we defeat common altgorithms 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." + dna_cost = 1 + +//Prevents AIs tracking you but makes you easily detectable to the human-eye. +/obj/effect/proc_holder/changeling/digitalcamo/sting_action(var/mob/user) + + if(user.digitalcamo) + user << "We return to normal." + else + user << "We distort our form to prevent AI-tracking." + user.digitalcamo = !user.digitalcamo + + feedback_add_details("changeling_powers","CAM") + return 1 diff --git a/code/game/gamemodes/changeling/powers/epinephrine.dm b/code/game/gamemodes/changeling/powers/epinephrine.dm new file mode 100644 index 00000000000..55ce85cf88d --- /dev/null +++ b/code/game/gamemodes/changeling/powers/epinephrine.dm @@ -0,0 +1,27 @@ +/obj/effect/proc_holder/changeling/epinephrine + name = "Epinephrine Overdose" + desc = "We evolve additional sacs of adrenaline throughout our body." + helptext = "Removes all stuns instantly and adds a short-term reduction in further stuns. Can be used while unconscious. Continued use poisons the body." + chemical_cost = 30 + dna_cost = 2 + req_human = 1 + req_stat = UNCONSCIOUS + +//Recover from stuns. +/obj/effect/proc_holder/changeling/epinephrine/sting_action(var/mob/living/user) + + if(user.lying) + user << "We arise." + else + user << "Adrenaline rushes through us." + user.stat = 0 + user.SetParalysis(0) + user.SetStunned(0) + user.SetWeakened(0) + user.lying = 0 + user.update_canmove() + user.reagents.add_reagent("synaptizine", 20) + user.adjustStaminaLoss(-75) + + feedback_add_details("changeling_powers","UNS") + return 1 diff --git a/code/game/gamemodes/changeling/powers/fakedeath.dm b/code/game/gamemodes/changeling/powers/fakedeath.dm new file mode 100644 index 00000000000..9a4b144cc71 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/fakedeath.dm @@ -0,0 +1,36 @@ +/obj/effect/proc_holder/changeling/fakedeath + name = "Regenerative Stasis" + desc = "We fall into a stasis, allowing us to regenerate." + chemical_cost = 15 + dna_cost = 0 + req_dna = 1 + req_stat = DEAD + max_genetic_damage = 100 + + +//Fake our own death and fully heal. You will appear to be dead but regenerate fully after a short delay. +/obj/effect/proc_holder/changeling/fakedeath/sting_action(var/mob/living/user) + + user << "We begin our stasis, preparing energy to arise once more." + + user.status_flags |= FAKEDEATH //play dead + user.update_canmove() + + if(user.stat != DEAD) + user.emote("deathgasp") + user.tod = worldtime2text() + + spawn(800) + if(user && user.mind && user.mind.changeling && user.mind.changeling.purchasedpowers) + user << "We are ready to regenerate." + user.mind.changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/revive(null) + + feedback_add_details("changeling_powers","FD") + return 1 + +/obj/effect/proc_holder/changeling/fakedeath/can_sting(var/mob/user) + if(user.status_flags & FAKEDEATH) + return + if(!user.stat && alert("Are we sure we wish to fake our death?",,"Yes","No") == "No")//Confirmation for living changelings if they want to fake their death + return + return ..() \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/fleshmend.dm b/code/game/gamemodes/changeling/powers/fleshmend.dm new file mode 100644 index 00000000000..97889d1c9e3 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/fleshmend.dm @@ -0,0 +1,25 @@ +/obj/effect/proc_holder/changeling/fleshmend + name = "Fleshmend" + desc = "Our flesh rapidly regenerates, healing our wounds." + helptext = "Heals a moderate amount of damage over a short period of time. Can be used while unconscious." + chemical_cost = 25 + dna_cost = 2 + req_stat = UNCONSCIOUS + +//Starts healing you every second for 10 seconds. Can be used whilst unconscious. +/obj/effect/proc_holder/changeling/fleshmend/sting_action(var/mob/living/user) + user << "We begin to heal rapidly." + if(ishuman(user)) + var/mob/living/carbon/human/H = user + H.restore_blood() + H.shock_stage = 0 + spawn(1) + H.fixblood() + spawn(0) + for(var/i = 0, i<10,i++) + user.heal_overall_damage(10, 10) + user.adjustOxyLoss(-10) + sleep(10) + + feedback_add_details("changeling_powers","RR") + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/glands.dm b/code/game/gamemodes/changeling/powers/glands.dm new file mode 100644 index 00000000000..d08bd3021aa --- /dev/null +++ b/code/game/gamemodes/changeling/powers/glands.dm @@ -0,0 +1,13 @@ +/obj/effect/proc_holder/changeling/glands + name = "Engorged Chemical Glands" + desc = "Our chemical glands swell, permitting us to store more chemicals inside of them." + helptext = "Allows us to store an extra 25 units of chemicals, and doubles production rate." + dna_cost = 2 + chemical_cost = -1 + +/obj/effect/proc_holder/changeling/glands/on_purchase(var/mob/user) + ..() + var/datum/changeling/changeling=user.mind.changeling + changeling.chem_storage += 25 + changeling.chem_recharge_rate *=2 + return \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/hivemind.dm b/code/game/gamemodes/changeling/powers/hivemind.dm new file mode 100644 index 00000000000..853b7081fed --- /dev/null +++ b/code/game/gamemodes/changeling/powers/hivemind.dm @@ -0,0 +1,92 @@ +//HIVEMIND COMMUNICATION (:g) +/obj/effect/proc_holder/changeling/hivemind_comms + name = "Hivemind Communication" + desc = "We tune our senses to the airwaves to allow us to discreetly communicate and exchange DNA with other changelings." + helptext = "We will be able to talk with other changelings with :g. Exchanged DNA do not count towards absorb objectives." + dna_cost = 0 + chemical_cost = -1 + +/obj/effect/proc_holder/changeling/hivemind_comms/on_purchase(var/mob/user) + ..() + var/datum/changeling/changeling=user.mind.changeling + changeling.changeling_speak = 1 + user << "Use say \":g message\" to communicate with the other changelings." + var/obj/effect/proc_holder/changeling/hivemind_upload/S1 = new + if(!changeling.has_sting(S1)) + changeling.purchasedpowers+=S1 + var/obj/effect/proc_holder/changeling/hivemind_download/S2 = new + if(!changeling.has_sting(S2)) + changeling.purchasedpowers+=S2 + return + +// HIVE MIND UPLOAD/DOWNLOAD DNA +var/list/datum/dna/hivemind_bank = list() + +/obj/effect/proc_holder/changeling/hivemind_upload + name = "Hive Channel DNA" + desc = "Allows us to channel DNA in the airwaves to allow other changelings to absorb it." + chemical_cost = 10 + dna_cost = -1 + +/obj/effect/proc_holder/changeling/hivemind_upload/sting_action(var/mob/user) + var/datum/changeling/changeling = user.mind.changeling + var/list/names = list() + for(var/datum/dna/DNA in (changeling.absorbed_dna+changeling.protected_dna)) + if(!(DNA in hivemind_bank)) + names += DNA.real_name + + if(names.len <= 0) + user << "The airwaves already have all of our DNA." + return + + var/chosen_name = input("Select a DNA to channel: ", "Channel DNA", null) as null|anything in names + if(!chosen_name) + return + + var/datum/dna/chosen_dna = changeling.GetDNA(chosen_name) + if(!chosen_dna) + return + + hivemind_bank += chosen_dna + user << "We channel the DNA of [chosen_name] to the air." + feedback_add_details("changeling_powers","HU") + return 1 + +/obj/effect/proc_holder/changeling/hivemind_download + name = "Hive Absorb DNA" + desc = "Allows us to absorb DNA that has been channeled to the airwaves. Does not count towards absorb objectives." + chemical_cost = 10 + dna_cost = -1 + +/obj/effect/proc_holder/changeling/hivemind_download/can_sting(var/mob/living/carbon/user) + if(!..()) + return + var/datum/changeling/changeling = user.mind.changeling + if(changeling.absorbed_dna[1] == user.dna)//If our current DNA is the stalest, we gotta ditch it. + user << "We have reached our capacity to store genetic information! We must transform before absorbing more." + return + return 1 + +/obj/effect/proc_holder/changeling/hivemind_download/sting_action(var/mob/user) + var/datum/changeling/changeling = user.mind.changeling + var/list/names = list() + for(var/datum/dna/DNA in hivemind_bank) + if(!(DNA in changeling.absorbed_dna)) + names[DNA.real_name] = DNA + + if(names.len <= 0) + user << "There's no new DNA to absorb from the air." + return + + var/S = input("Select a DNA absorb from the air: ", "Absorb DNA", null) as null|anything in names + if(!S) return + var/datum/dna/chosen_dna = names[S] + if(!chosen_dna) + return + + if(changeling.absorbed_dna.len) + changeling.absorbed_dna.Cut(1,2) + changeling.store_dna(chosen_dna, user) + user << "We absorb the DNA of [S] from the air." + feedback_add_details("changeling_powers","HD") + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/humanform.dm b/code/game/gamemodes/changeling/powers/humanform.dm new file mode 100644 index 00000000000..42e0bb3dad1 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/humanform.dm @@ -0,0 +1,74 @@ +/obj/effect/proc_holder/changeling/humanform + name = "Human form" + desc = "We change into a human." + chemical_cost = 5 + genetic_damage = 3 + req_dna = 1 + max_genetic_damage = 3 + + +//Transform into a human. +/obj/effect/proc_holder/changeling/humanform/sting_action(var/mob/living/carbon/user) + var/datum/changeling/changeling = user.mind.changeling + var/list/names = list() + for(var/datum/dna/DNA in (changeling.absorbed_dna+changeling.protected_dna)) + names += "[DNA.real_name]" + + var/chosen_name = input("Select the target DNA: ", "Target DNA", null) as null|anything in names + if(!chosen_name) + return + + var/datum/dna/chosen_dna = changeling.GetDNA(chosen_name) + if(!chosen_dna) + return + if(!user) + return 0 + user << "We transform our appearance." + user.dna = chosen_dna + + var/list/implants = list() + for (var/obj/item/weapon/implant/I in user) //Still preserving implants + implants += I + + for(var/obj/item/W in src) + user.unEquip(W) + if (user.client) + user.client.screen -= W + if (W) + W.loc = user.loc + W.dropped(user) + W.layer = initial(W.layer) + + var/mob/living/carbon/human/O = new /mob/living/carbon/human( user, delay_ready_dna=1 ) + if (user.dna.GetUIState(DNA_UI_GENDER)) + O.gender = FEMALE + else + O.gender = MALE + O.dna = user.dna.Clone() + user.dna = null + O.real_name = chosen_dna.real_name + O.set_species() + for(var/obj/T in user) + del(T) + + O.loc = user.loc + + O.UpdateAppearance() + domutcheck(O, null) + O.setToxLoss(user.getToxLoss()) + O.adjustBruteLoss(user.getBruteLoss()) + O.setOxyLoss(user.getOxyLoss()) + O.adjustFireLoss(user.getFireLoss()) + O.stat = user.stat + for (var/obj/item/weapon/implant/I in implants) + I.loc = O + I.implanted = O + + user.mind.transfer_to(O) + O.changeling_update_languages(changeling.absorbed_languages) + O.mind.changeling.purchasedpowers -= src + //O.mind.changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/lesserform(null) + feedback_add_details("changeling_powers","LFT") + qdel(user) + return 1 + diff --git a/code/game/gamemodes/changeling/powers/lesserform.dm b/code/game/gamemodes/changeling/powers/lesserform.dm new file mode 100644 index 00000000000..a769ee47bd0 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/lesserform.dm @@ -0,0 +1,67 @@ +/obj/effect/proc_holder/changeling/lesserform + name = "Lesser form" + desc = "We debase ourselves and become lesser. We become a monkey." + chemical_cost = 5 + dna_cost = 1 + genetic_damage = 3 + req_human = 1 + +//Transform into a monkey. +/obj/effect/proc_holder/changeling/lesserform/sting_action(var/mob/living/carbon/human/user) + var/datum/changeling/changeling = user.mind.changeling + if(!user) + return 0 + if(user.has_brain_worms()) + user << "We cannot perform this ability at the present time!" + return + user << "Our genes cry out!" + + var/mob/living/carbon/C = user + + //TODO replace with monkeyize proc + var/list/implants = list() //Try to preserve implants. + for(var/obj/item/weapon/implant/W in C) + implants += W + + C.monkeyizing = 1 + C.canmove = 0 + C.icon = null + C.overlays.Cut() + C.invisibility = 101 + + var/atom/movable/overlay/animation = new /atom/movable/overlay( C.loc ) + animation.icon_state = "blank" + animation.icon = 'icons/mob/mob.dmi' + animation.master = src + flick("h2monkey", animation) + sleep(30) + del(animation) + + var/mob/living/carbon/monkey/O = new /mob/living/carbon/monkey(src) + O.dna = C.dna.Clone() + C.dna = null + + for(var/obj/item/W in C) + C.unEquip(W) + for(var/obj/T in C) + del(T) + + O.loc = C.loc + O.name = "monkey ([copytext(md5(C.real_name), 2, 6)])" + O.setToxLoss(C.getToxLoss()) + O.adjustBruteLoss(C.getBruteLoss()) + O.setOxyLoss(C.getOxyLoss()) + O.adjustFireLoss(C.getFireLoss()) + O.stat = C.stat + O.a_intent = "harm" + for(var/obj/item/weapon/implant/I in implants) + I.loc = O + I.implanted = O + + C.mind.transfer_to(O) + O.mind.changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/humanform(null) + O.changeling_update_languages(changeling.absorbed_languages) + + feedback_add_details("changeling_powers","LF") + qdel(C) + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/mimic_voice.dm b/code/game/gamemodes/changeling/powers/mimic_voice.dm new file mode 100644 index 00000000000..9d637245196 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/mimic_voice.dm @@ -0,0 +1,28 @@ +/obj/effect/proc_holder/changeling/mimicvoice + 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." + chemical_cost = 0 //constant chemical drain hardcoded + dna_cost = 1 + req_human = 1 + + +// Fake Voice +/obj/effect/proc_holder/changeling/mimicvoice/sting_action(var/mob/user) + var/datum/changeling/changeling=user.mind.changeling + if(changeling.mimicing) + changeling.mimicing = "" + changeling.chem_recharge_slowdown -= 0.5 + user << "We return our vocal glands to their original position." + return + + var/mimic_voice = stripped_input(user, "Enter a name to mimic.", "Mimic Voice", null, MAX_NAME_LEN) + if(!mimic_voice) + return + + changeling.mimicing = mimic_voice + changeling.chem_recharge_slowdown += 0.5 + user << "We shape our glands to take the voice of [mimic_voice], this will stop us from regenerating chemicals while active." + user << "Use this power again to return to our original voice and reproduce chemicals again." + + feedback_add_details("changeling_powers","MV") diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm new file mode 100644 index 00000000000..f1a9e3d1a52 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/mutations.dm @@ -0,0 +1,338 @@ +/* + Changeling Mutations! ~By Miauw (ALL OF IT :V) + Contains: + Arm Blade + Space Suit + Shield + Armor +*/ + + +//Parent to shields and blades because muh copypasted code. +/obj/effect/proc_holder/changeling/weapon + name = "Organic Weapon" + desc = "Go tell a coder if you see this" + helptext = "Yell at coderbus" + chemical_cost = 1000 + dna_cost = -1 + genetic_damage = 1000 + + var/weapon_type + var/weapon_name_simple + +/obj/effect/proc_holder/changeling/weapon/try_to_sting(var/mob/user, var/mob/target) + if(istype(user.l_hand, weapon_type)) //Not the nicest way to do it, but eh + del(user.l_hand) + user.visible_message("With a sickening crunch, [user] reforms his [weapon_name_simple] into an arm!", "We assimilate the [weapon_name_simple] back into our body.", "With a sickening crunch, [user] reforms his [weapon_name_simple] into an arm!", "We assimilate the [weapon_name_simple] back into our body.", "[H] casts off their [suit_name_simple]!", "We cast off our [suit_name_simple][genetic_damage > 0 ? ", temporarily weakening our genomes." : "."]", "You hear the organic matter ripping and tearing!") + del(H.wear_suit) + del(H.head) + H.update_inv_wear_suit() + H.update_inv_head() + H.update_hair() + + if(blood_on_castoff) + var/turf/simulated/T = get_turf(H) + if(istype(T)) + T.add_blood(H) //So real blood decals + playsound(H.loc, 'sound/effects/splat.ogg', 50, 1) //So real sounds + + changeling.geneticdamage += genetic_damage //Casting off a space suit leaves you weak for a few seconds. + changeling.chem_recharge_slowdown -= recharge_slowdown + return + ..(H, target) + +/obj/effect/proc_holder/changeling/suit/sting_action(var/mob/living/carbon/human/user) + if(!user.unEquip(user.wear_suit)) + user << "\the [user.wear_suit] is stuck to your body, you cannot grow a [suit_name_simple] over it!" + return + if(!user.unEquip(user.head)) + user << "\the [user.head] is stuck on your head, you cannot grow a [helmet_name_simple] over it!" + return + + user.unEquip(user.head) + user.unEquip(user.wear_suit) + + user.equip_to_slot_if_possible(new suit_type(user), slot_wear_suit, 1, 1, 1) + user.equip_to_slot_if_possible(new helmet_type(user), slot_head, 1, 1, 1) + + var/datum/changeling/changeling = user.mind.changeling + changeling.chem_recharge_slowdown += recharge_slowdown + return 1 + + +//fancy headers yo +/***************************************\ +|***************ARM BLADE***************| +\***************************************/ +/obj/effect/proc_holder/changeling/weapon/arm_blade + name = "Arm Blade" + desc = "We reform one of our arms into a deadly blade." + helptext = "Cannot be used while in lesser form." + chemical_cost = 20 + dna_cost = 2 + genetic_damage = 10 + req_human = 1 + max_genetic_damage = 20 + weapon_type = /obj/item/weapon/melee/arm_blade + weapon_name_simple = "blade" + +/obj/item/weapon/melee/arm_blade + name = "arm blade" + desc = "A grotesque blade made out of bone and flesh that cleaves through people as a hot knife through butter" + icon = 'icons/obj/weapons.dmi' + icon_state = "arm_blade" + item_state = "arm_blade" + flags = ABSTRACT | NODROP + icon_override = 'icons/mob/in-hand/changeling.dmi' + w_class = 5.0 + sharp = 1 + edge = 1 + force = 25 + throwforce = 0 //Just to be on the safe side + throw_range = 0 + throw_speed = 0 + +/obj/item/weapon/melee/arm_blade/New() + ..() + if(ismob(loc)) + loc.visible_message("A grotesque blade forms around [loc.name]\'s arm!", "Our arm twists and mutates, transforming it into a deadly blade.", "You hear organic matter ripping and tearing!") + +/obj/item/weapon/melee/arm_blade/dropped(mob/user) + user.visible_message("With a sickening crunch, [user] reforms his blade into an arm!", "We assimilate the blade back into our body.", "" + return + + else if(A.locked) + user << "The airlock's bolts prevent it from being forced." + return + + else + //user.say("Heeeeeeeeeerrre's Johnny!") + user.visible_message("[user] forces the door to open with \his [src]!", "We force the door to open.", "You hear a metal screeching sound.") + A.open(1) + + +/***************************************\ +|****************SHIELD*****************| +\***************************************/ +/obj/effect/proc_holder/changeling/weapon/shield + name = "Organic Shield" + desc = "We reform one of our arms into a hard shield." + helptext = "Organic tissue cannot resist damage forever, the shield will break after it is hit too much. The more genomes we absorb, the stronger it is. Cannot be used while in lesser form." + chemical_cost = 20 + dna_cost = 1 + genetic_damage = 12 + req_human = 1 + max_genetic_damage = 20 + + weapon_type = /obj/item/weapon/shield/changeling + weapon_name_simple = "shield" + +/obj/effect/proc_holder/changeling/weapon/shield/sting_action(var/mob/user) + var/datum/changeling/changeling = user.mind.changeling //So we can read the absorbedcount. + if(!changeling) + return + + var/obj/item/weapon/shield/changeling/S = ..(user) + if(!S) + return + S.remaining_uses = round(changeling.absorbedcount * 3) + return 1 + +/obj/item/weapon/shield/changeling + name = "shield-like mass" + desc = "A mass of tough, boney tissue. You can still see the fingers as a twisted pattern in the shield." + flags = NODROP + icon = 'icons/obj/weapons.dmi' + icon_state = "ling_shield" + icon_override = 'icons/mob/in-hand/changeling.dmi' + + var/remaining_uses //Set by the changeling ability. + +/obj/item/weapon/shield/changeling/New() + ..() + if(ismob(loc)) + loc.visible_message("The end of [loc.name]\'s hand inflates rapidly, forming a huge shield-like mass!", "We inflate our hand into a strong shield.", "You hear organic matter ripping and tearing!") + +/obj/item/weapon/shield/changeling/dropped() + del(src) + +/obj/item/weapon/shield/changeling/IsShield() + if(remaining_uses < 1) + if(ishuman(loc)) + var/mob/living/carbon/human/H = loc + H.visible_message("With a sickening crunch, [H] reforms his shield into an arm!", "We assimilate our shield into our body", "[loc.name]\'s flesh rapidly inflates, forming a bloated mass around their body!", "We inflate our flesh, creating a spaceproof suit!", "You hear organic matter ripping and tearing!") + processing_objects += src + +/obj/item/clothing/suit/space/changeling/dropped() + del(src) + +/obj/item/clothing/suit/space/changeling/process() + if(ishuman(loc)) + var/mob/living/carbon/human/H = loc + H.reagents.add_reagent("dexalinp", REAGENTS_METABOLISM) + +/obj/item/clothing/head/helmet/space/changeling + name = "flesh mass" + icon_state = "lingspacehelmet" + desc = "A covering of pressure and temperature-resistant organic tissue with a glass-like chitin front." + flags = HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPSPRESSUREDMAGE | NODROP + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) + +/obj/item/clothing/head/helmet/space/changeling/dropped() + del(src) + + +/***************************************\ +|*****************ARMOR*****************| +\***************************************/ +/obj/effect/proc_holder/changeling/suit/armor + name = "Chitinous Armor" + desc = "We turn our skin into tough chitin to protect us from damage." + helptext = "Upkeep of the armor requires a low expenditure of chemicals. The armor is strong against brute force, but does not provide much protection from lasers. Retreating the armor damages our genomes. Cannot be used in lesser form." + chemical_cost = 20 + dna_cost = 2 + genetic_damage = 11 + req_human = 1 + max_genetic_damage = 20 + + suit_type = /obj/item/clothing/suit/armor/changeling + helmet_type = /obj/item/clothing/head/helmet/changeling + suit_name_simple = "armor" + helmet_name_simple = "helmet" + recharge_slowdown = 0.25 + +/obj/item/clothing/suit/armor/changeling + name = "chitinous mass" + desc = "A tough, hard covering of black chitin." + icon_state = "lingarmor" + flags = NODROP + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS + slowdown = 2 + armor = list(melee = 65, bullet = 20, laser = 10, energy = 13, bomb = 0, bio = 0, rad = 0) + flags_inv = HIDEJUMPSUIT + cold_protection = 0 + heat_protection = 0 + +/obj/item/clothing/suit/armor/changeling/New() + ..() + if(ismob(loc)) + loc.visible_message("[loc.name]\'s flesh turns black, quickly transforming into a hard, chitinous mass!", "We harden our flesh, creating a suit of armor!", "You hear organic matter ripping and tearing!") + +/obj/item/clothing/suit/armor/changeling/dropped() + del(src) + +/obj/item/clothing/head/helmet/changeling + name = "chitinous mass" + desc = "A tough, hard covering of black chitin with transparent chitin in front." + icon_state = "lingarmorhelmet" + flags = HEADCOVERSEYES | BLOCKHAIR | NODROP + armor = list(melee = 70, bullet = 15, laser = 7,energy = 10, bomb = 5, bio = 2, rad = 0) + flags_inv = HIDEEARS + +/obj/item/clothing/head/helmet/changeling/dropped() + del(src) diff --git a/code/game/gamemodes/changeling/powers/panacea.dm b/code/game/gamemodes/changeling/powers/panacea.dm new file mode 100644 index 00000000000..f6721af7f47 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/panacea.dm @@ -0,0 +1,25 @@ +/obj/effect/proc_holder/changeling/panacea + name = "Anatomic Panacea" + desc = "Expels impurifications from our form; curing diseases, removing toxins and radiation, and resetting our genetic code completely." + helptext = "Can be used while unconscious." + chemical_cost = 20 + dna_cost = 1 + req_stat = UNCONSCIOUS + +//Heals the things that the other regenerative abilities don't. +/obj/effect/proc_holder/changeling/panacea/sting_action(var/mob/user) + + user << "We cleanse impurities from our form." + user.reagents.add_reagent("ryetalyn", 10) + user.reagents.add_reagent("hyronalin", 10) + user.reagents.add_reagent("anti_toxin", 20) + + if(istype(user, /mob/living/carbon)) + var/mob/living/carbon/C = user + if(C.virus2.len) + for (var/ID in C.virus2) + var/datum/disease2/disease/V = C.virus2[ID] + C.antibodies |= V.antigen + + feedback_add_details("changeling_powers","AP") + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm new file mode 100644 index 00000000000..526172fdf38 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/revive.dm @@ -0,0 +1,73 @@ +/obj/effect/proc_holder/changeling/revive + name = "Regenerate" + desc = "We regenerate, healing all damage from our form." + req_stat = DEAD + +//Revive from regenerative stasis +/obj/effect/proc_holder/changeling/revive/sting_action(var/mob/living/carbon/user) + + if(user.stat == DEAD) + dead_mob_list -= user + living_mob_list += user + user.stat = CONSCIOUS + user.tod = null + user.setToxLoss(0) + user.setOxyLoss(0) + user.setCloneLoss(0) + user.setBrainLoss(0) + user.SetParalysis(0) + user.SetStunned(0) + user.SetWeakened(0) + user.radiation = 0 + user.eye_blind = 0 + user.eye_blurry = 0 + user.ear_deaf = 0 + user.ear_damage = 0 + user.heal_overall_damage(user.getBruteLoss(), user.getFireLoss()) + user.reagents.clear_reagents() + user.germ_level = 0 + user.next_pain_time = 0 + user.traumatic_shock = 0 + if(ishuman(user)) + var/mob/living/carbon/human/H = user + H.restore_blood() + H.shock_stage = 0 + spawn(1) + H.fixblood() + for(var/organ_name in H.organs_by_name) + var/datum/organ/external/O = H.organs_by_name[organ_name] + for(var/obj/item/weapon/shard/shrapnel/s in O.implants) + if(istype(s)) + O.implants -= s + H.contents -= s + del(s) + O.amputated = 0 + O.brute_dam = 0 + O.burn_dam = 0 + O.damage_state = "00" + O.germ_level = 0 + O.hidden = null + O.number_wounds = 0 + O.open = 0 + O.perma_injury = 0 + O.stage = 0 + O.status = 0 + O.trace_chemicals = list() + O.wounds = list() + O.wound_update_accuracy = 1 + for(var/n in H.internal_organs_by_name) + var/datum/organ/internal/IO = H.internal_organs_by_name[n] + IO.damage = 0 + IO.trace_chemicals = list() + H.updatehealth() + user << "We have regenerated." + + user.regenerate_icons() + user.hud_updateflag |= 1 << HEALTH_HUD + user.hud_updateflag |= 1 << STATUS_HUD + + user.status_flags &= ~(FAKEDEATH) + user.update_canmove() + user.mind.changeling.purchasedpowers -= src + feedback_add_details("changeling_powers","CR") + return 1 diff --git a/code/game/gamemodes/changeling/powers/shriek.dm b/code/game/gamemodes/changeling/powers/shriek.dm new file mode 100644 index 00000000000..cb9cc06c62b --- /dev/null +++ b/code/game/gamemodes/changeling/powers/shriek.dm @@ -0,0 +1,46 @@ +/obj/effect/proc_holder/changeling/resonant_shriek + name = "Resonant Shriek" + desc = "Our lungs and vocal chords shift, allowing us to briefly emit a noise that deafens and confuses the weak-minded." + helptext = "Emits a high-frequency sound that confuses and deafens humans, blows out nearby lights and overloads cyborg sensors." + chemical_cost = 20 + dna_cost = 1 + req_human = 1 + +//A flashy ability, good for crowd control and sewing chaos. +/obj/effect/proc_holder/changeling/resonant_shriek/sting_action(var/mob/user) + for(var/mob/living/M in get_mobs_in_view(4, user)) + if(iscarbon(M)) + if(!M.mind || !M.mind.changeling) + M.ear_deaf = max(0, M.ear_deaf + 30) + M.ear_damage = max(0, M.ear_damage) + M.confused += 20 + M.Jitter(50) + else + M << sound('sound/effects/screech.ogg') + + if(issilicon(M)) + M << sound('sound/weapons/flash.ogg') + M.Weaken(rand(5,10)) + + for(var/obj/machinery/light/L in range(4, user)) + L.on = 1 + L.broken() + + feedback_add_details("changeling_powers","RS") + return 1 + +/obj/effect/proc_holder/changeling/dissonant_shriek + name = "Dissonant Shriek" + desc = "We shift our vocal cords to release a high-frequency sound that overloads nearby electronics." + chemical_cost = 20 + dna_cost = 1 + +//A flashy ability, good for crowd control and sewing chaos. +/obj/effect/proc_holder/changeling/dissonant_shriek/sting_action(var/mob/user) + for(var/obj/machinery/light/L in range(5, usr)) + L.on = 1 + L.broken() + empulse(get_turf(user), 2, 5, 1) + return 1 + + diff --git a/code/game/gamemodes/changeling/powers/spiders.dm b/code/game/gamemodes/changeling/powers/spiders.dm new file mode 100644 index 00000000000..52f8ecd31bd --- /dev/null +++ b/code/game/gamemodes/changeling/powers/spiders.dm @@ -0,0 +1,16 @@ +/obj/effect/proc_holder/changeling/spiders + name = "Spread Infestation" + desc = "Our form divides, creating arachnids which will grow into deadly beasts." + helptext = "The spiders are thoughtless creatures, and may attack their creators when fully grown. Requires at least 5 DNA absorptions." + chemical_cost = 45 + dna_cost = 1 + req_dna = 5 + +//Makes some spiderlings. Good for setting traps and causing general trouble. +/obj/effect/proc_holder/changeling/spiders/sting_action(var/mob/user) + for(var/i=0, i<4, i++) + var/obj/effect/spider/spiderling/S = new(user.loc) + S.grow_as = /mob/living/simple_animal/hostile/giant_spider/hunter + + feedback_add_details("changeling_powers","SI") + return 1 diff --git a/code/game/gamemodes/changeling/powers/strained_muscles.dm b/code/game/gamemodes/changeling/powers/strained_muscles.dm new file mode 100644 index 00000000000..7c5cded0c91 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/strained_muscles.dm @@ -0,0 +1,51 @@ +//Strained Muscles: Temporary speed boost at the cost of rapid damage +//Limited because of hardsuits and such; ideally, used for a quick getaway + +/obj/effect/proc_holder/changeling/strained_muscles + name = "Strained Muscles" + desc = "We evolve the ability to reduce the acid buildup in our muscles, allowing us to move much faster." + helptext = "The strain will make us tired, and we will rapidly become fatigued. Standard weight restrictions, like hardsuits, still apply. Cannot be used in lesser form." + chemical_cost = 0 + dna_cost = 1 + req_human = 1 + var/stacks = 0 //Increments every 5 seconds; damage increases over time + var/active = 0 //Whether or not you are a hedgehog + +/obj/effect/proc_holder/changeling/strained_muscles/sting_action(var/mob/living/carbon/user) + active = !active + if(active) + user << "Our muscles tense and strengthen." + else + user.status_flags &= ~GOTTAGOFAST + user << "Our muscles relax." + if(stacks >= 10) + user << "We collapse in exhaustion." + user.Weaken(3) + user.emote("gasp") + + while(active) + user.status_flags |= GOTTAGOFAST + if(user.stat || user.staminaloss >= 90) + active = 0 //Let's use something exact instead of !active where we can. + user << "Our muscles relax without the energy to strengthen them." + user.status_flags &= ~GOTTAGOFAST + user.Weaken(2) + user.emote("gasp") + break + + stacks++ + //user.take_organ_damage(stacks * 0.03, 0) + user.staminaloss += stacks * 1.3 //At first the changeling may regenerate stamina fast enough to nullify fatigue, but it will stack + + if(stacks == 11) //Warning message that the stacks are getting too high + user << "Our legs are really starting to hurt..." + + sleep(40) + + while(!active) //Damage stacks decrease fairly rapidly while not in sanic mode + if(stacks >= 1) + stacks-- + sleep(20) + + feedback_add_details("changeling_powers","SANIC") + return 1 diff --git a/code/game/gamemodes/changeling/powers/tiny_prick.dm b/code/game/gamemodes/changeling/powers/tiny_prick.dm new file mode 100644 index 00000000000..6158b8672bd --- /dev/null +++ b/code/game/gamemodes/changeling/powers/tiny_prick.dm @@ -0,0 +1,191 @@ +/obj/effect/proc_holder/changeling/sting + name = "Tiny Prick" + desc = "Stabby stabby" + var/sting_icon = null + +/obj/effect/proc_holder/changeling/sting/Click() + var/mob/user = usr + if(!user || !user.mind || !user.mind.changeling) + return + if(!(user.mind.changeling.chosen_sting)) + set_sting(user) + else + unset_sting(user) + return + +/obj/effect/proc_holder/changeling/sting/proc/set_sting(var/mob/user) + user << "We prepare our sting, use alt+click or middle mouse button on target to sting them." + user.mind.changeling.chosen_sting = src + +/obj/effect/proc_holder/changeling/sting/proc/unset_sting(var/mob/user) + user << "We retract our sting, we can't sting anyone for now." + user.mind.changeling.chosen_sting = null + +/mob/living/carbon/proc/unset_sting() + if(mind && mind.changeling && mind.changeling.chosen_sting) + src.mind.changeling.chosen_sting.unset_sting(src) + +/obj/effect/proc_holder/changeling/sting/can_sting(var/mob/user, var/mob/target) + if(!..()) + return + if(!user.mind.changeling.chosen_sting) + user << "We haven't prepared our sting yet!" + if(!iscarbon(target)) + return + if(ishuman(target)) + var/mob/living/carbon/human/H = target + if(H.species.flags & IS_SYNTHETIC) + user << "This won't work on synthetics." + return + if(!isturf(user.loc)) + return + if(get_dist(user, target) > (user.mind.changeling.sting_range)) + return //sanity check as AStar is still throwing insane stunts + if(!AStar(user.loc, target.loc, /turf/proc/AdjacentTurfs, /turf/proc/Distance, user.mind.changeling.sting_range)) + return //hope this ancient magic still works + if(target.mind && target.mind.changeling) + sting_feedback(user,target) + take_chemical_cost(user.mind.changeling) + return + return 1 + +/obj/effect/proc_holder/changeling/sting/sting_feedback(var/mob/user, var/mob/target) + if(!target) + return + user << "We stealthily sting [target.name]." + if(target.mind && target.mind.changeling) + target << "You feel a tiny prick." + add_logs(target, user, "unsuccessfully stung") + return 1 + + +/obj/effect/proc_holder/changeling/sting/transformation + name = "Transformation Sting" + desc = "We silently sting a human, injecting a retrovirus that forces them to transform." + helptext = "Does not provide a warning to others. The victim will transform much like a changeling would." + sting_icon = "sting_transform" + chemical_cost = 40 + dna_cost = 2 + var/datum/dna/selected_dna = null + +/obj/effect/proc_holder/changeling/sting/transformation/Click() + var/mob/user = usr + var/datum/changeling/changeling = user.mind.changeling + if(changeling.chosen_sting) + unset_sting(user) + return + selected_dna = changeling.select_dna("Select the target DNA: ", "Target DNA") + if(!selected_dna) + return + ..() + +/obj/effect/proc_holder/changeling/sting/transformation/can_sting(var/mob/user, var/mob/target) + if(!..()) + return + if((HUSK in target.mutations) || (!ishuman(target) && !ismonkey(target))) + user << "Our sting appears ineffective against its DNA." + return 0 + if(ishuman(target)) + var/mob/living/carbon/human/H = target + if(H.species.flags & NO_SCAN) //Prevents transforming slimes and killing them instantly + user << "This won't work on a creature with abnormal genetic material." + return 0 + return 1 + +/obj/effect/proc_holder/changeling/sting/transformation/sting_action(var/mob/user, var/mob/target) + add_logs(target, user, "stung", object="transformation sting", addition=" new identity is [selected_dna.real_name]") + var/datum/dna/NewDNA = selected_dna + if(ismonkey(target)) + user << "We stealthily sting [target.name]." + target.dna = NewDNA.Clone() + target.real_name = NewDNA.real_name + var/mob/living/carbon/human/H = target + if(istype(H)) + H.set_species() + target.UpdateAppearance() + domutcheck(target, null) + feedback_add_details("changeling_powers","TS") + return 1 + +obj/effect/proc_holder/changeling/sting/extract_dna + name = "Extract DNA Sting" + desc = "We stealthily sting a target and extract their DNA." + helptext = "Will give you the DNA of your target, allowing you to transform into them." + sting_icon = "sting_extract" + chemical_cost = 25 + dna_cost = 0 + +/obj/effect/proc_holder/changeling/sting/extract_dna/can_sting(var/mob/user, var/mob/target) + if(..()) + return user.mind.changeling.can_absorb_dna(user, target) + +/obj/effect/proc_holder/changeling/sting/extract_dna/sting_action(var/mob/user, var/mob/living/carbon/human/target) + add_logs(target, user, "stung", object="extraction sting") + if(!(user.mind.changeling.has_dna(target.dna))) + user.mind.changeling.absorb_dna(target, user) + feedback_add_details("changeling_powers","ED") + return 1 + +obj/effect/proc_holder/changeling/sting/mute + name = "Mute Sting" + desc = "We silently sting a human, completely silencing them for a short time." + helptext = "Does not provide a warning to the victim that they have been stung, until they try to speak and cannot." + sting_icon = "sting_mute" + chemical_cost = 20 + dna_cost = 2 + +/obj/effect/proc_holder/changeling/sting/mute/sting_action(var/mob/user, var/mob/living/carbon/target) + add_logs(target, user, "stung", object="mute sting") + target.silent += 30 + feedback_add_details("changeling_powers","MS") + return 1 + +obj/effect/proc_holder/changeling/sting/blind + name = "Blind Sting" + desc = "Temporarily blinds the target." + helptext = "This sting completely blinds a target for a short time." + sting_icon = "sting_blind" + chemical_cost = 25 + dna_cost = 1 + +/obj/effect/proc_holder/changeling/sting/blind/sting_action(var/mob/user, var/mob/target) + add_logs(target, user, "stung", object="blind sting") + target << "Your eyes burn horrifically!" + target.disabilities |= NEARSIGHTED + target.eye_blind = 20 + target.eye_blurry = 40 + feedback_add_details("changeling_powers","BS") + return 1 + +obj/effect/proc_holder/changeling/sting/LSD + name = "Hallucination Sting" + desc = "Causes terror in the target." + helptext = "We evolve the ability to sting a target with a powerful hallucinogenic chemical. The target does not notice they have been stung, and the effect occurs after 30 to 60 seconds." + sting_icon = "sting_lsd" + chemical_cost = 10 + dna_cost = 1 + +/obj/effect/proc_holder/changeling/sting/LSD/sting_action(var/mob/user, var/mob/living/carbon/target) + add_logs(target, user, "stung", object="LSD sting") + spawn(rand(300,600)) + if(target) + target.hallucination = max(400, target.hallucination) + feedback_add_details("changeling_powers","HS") + return 1 +/* +obj/effect/proc_holder/changeling/sting/cryo //Enable when mob cooling is fixed so that frostoil actually makes you cold, instead of mostly just hungry. + name = "Cryogenic Sting" + desc = "We silently sting a human with a cocktail of chemicals that freeze them." + helptext = "Does not provide a warning to the victim, though they will likely realize they are suddenly freezing." + sting_icon = "sting_cryo" + chemical_cost = 15 + dna_cost = 2 + +/obj/effect/proc_holder/changeling/sting/cryo/sting_action(var/mob/user, var/mob/target) + add_logs(target, user, "stung", object="cryo sting") + if(target.reagents) + target.reagents.add_reagent("frostoil", 30) + target.reagents.add_reagent("ice", 30) + feedback_add_details("changeling_powers","CS") + return 1 +*/ diff --git a/code/game/gamemodes/changeling/powers/transform.dm b/code/game/gamemodes/changeling/powers/transform.dm new file mode 100644 index 00000000000..f1ff51a42a2 --- /dev/null +++ b/code/game/gamemodes/changeling/powers/transform.dm @@ -0,0 +1,39 @@ +/obj/effect/proc_holder/changeling/transform + name = "Transform" + desc = "We take on the appearance and voice of one we have absorbed." + chemical_cost = 5 + dna_cost = 0 + req_dna = 1 + req_human = 1 + max_genetic_damage = 3 + +//Change our DNA to that of somebody we've absorbed. +/obj/effect/proc_holder/changeling/transform/sting_action(var/mob/living/carbon/human/user) + var/datum/changeling/changeling = user.mind.changeling + var/datum/dna/chosen_dna = changeling.select_dna("Select the target DNA: ", "Target DNA") + + if(!chosen_dna) + return + user.dna = chosen_dna.Clone() + user.real_name = chosen_dna.real_name + user.flavor_text = "" + if(ishuman(user)) + user.set_species() + user.UpdateAppearance() + domutcheck(user, null) + + user.changeling_update_languages(changeling.absorbed_languages) + + feedback_add_details("changeling_powers","TR") + return 1 + +/datum/changeling/proc/select_dna(var/prompt, var/title) + var/list/names = list() + for(var/datum/dna/DNA in (absorbed_dna+protected_dna)) + names += "[DNA.real_name]" + + var/chosen_name = input(prompt, title, null) as null|anything in names + if(!chosen_name) + return + var/datum/dna/chosen_dna = GetDNA(chosen_name) + return chosen_dna \ No newline at end of file diff --git a/code/game/gamemodes/changeling/traitor_chan.dm b/code/game/gamemodes/changeling/traitor_chan.dm index 193a2e3574d..ce4c8f77887 100644 --- a/code/game/gamemodes/changeling/traitor_chan.dm +++ b/code/game/gamemodes/changeling/traitor_chan.dm @@ -7,7 +7,7 @@ required_players_secret = 10 required_enemies = 2 recommended_enemies = 3 - var/protected_species_changeling = list("Machine") + var/protected_species_changeling = list("Machine", "Slime People") /datum/game_mode/traitor/changeling/announce() world << "The current game mode is - Traitor+Changeling!" @@ -24,11 +24,11 @@ for(var/job in restricted_jobs)//Removing robots from the list if(player.assigned_role == job) possible_changelings -= player - + for(var/mob/new_player/player in player_list) if((player.mind in possible_changelings) && (player.client.prefs.species in protected_species_changeling)) possible_changelings -= player.mind - + if(possible_changelings.len>0) var/datum/mind/changeling = pick(possible_changelings) //possible_changelings-=changeling diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index 473afa46c1e..c856fbd4b18 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -132,7 +132,7 @@ if (mob.mind) if (mob.mind.assigned_role == "Clown") mob << "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself." - mob.mutations.Remove(M_CLUMSY) + mob.mutations.Remove(CLUMSY) add_cult_viewpoint(mob) // give them a viewpoint diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 81c3b5f19d7..be1e71c6bb4 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -3,7 +3,6 @@ desc = "An arcane weapon wielded by the followers of Nar-Sie" icon_state = "cultblade" item_state = "cultblade" - flags = FPRINT | TABLEPASS w_class = 4 force = 30 throwforce = 10 @@ -34,7 +33,7 @@ icon_state = "culthood" desc = "A hood worn by the followers of Nar-Sie." flags_inv = HIDEFACE - flags = FPRINT|TABLEPASS|HEADCOVERSEYES + flags = HEADCOVERSEYES armor = list(melee = 30, bullet = 10, laser = 5,energy = 5, bomb = 0, bio = 0, rad = 0) cold_protection = HEAD min_cold_protection_temperature = SPACE_HELMET_MIN_COLD_PROTECTION_TEMPERATURE @@ -55,7 +54,6 @@ desc = "A set of armored robes worn by the followers of Nar-Sie" icon_state = "cultrobes" item_state = "cultrobes" - flags = FPRINT | TABLEPASS body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS allowed = list(/obj/item/weapon/tome,/obj/item/weapon/melee/cultblade) armor = list(melee = 50, bullet = 30, laser = 50,energy = 20, bomb = 25, bio = 10, rad = 0) @@ -68,7 +66,7 @@ item_state = "magus" desc = "A helm worn by the followers of Nar-Sie." flags_inv = HIDEFACE - flags = FPRINT|TABLEPASS|HEADCOVERSEYES|HEADCOVERSMOUTH|BLOCKHAIR + flags = HEADCOVERSEYES | HEADCOVERSMOUTH | BLOCKHAIR armor = list(melee = 30, bullet = 30, laser = 30,energy = 20, bomb = 0, bio = 0, rad = 0) siemens_coefficient = 0 loose = 6 // mostly one size fits all @@ -78,7 +76,6 @@ desc = "A set of armored robes worn by the followers of Nar-Sie" icon_state = "magusred" item_state = "magusred" - flags = FPRINT | TABLEPASS body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS allowed = list(/obj/item/weapon/tome,/obj/item/weapon/melee/cultblade) armor = list(melee = 50, bullet = 30, laser = 50,energy = 20, bomb = 25, bio = 10, rad = 0) diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 02e20eb7a2f..65310a6b250 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -72,13 +72,11 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", blood.override = 1 for(var/mob/living/silicon/ai/AI in player_list) AI.client.images += blood - cultNetwork.viewpoints+=src - cultNetwork.addViewpoint(src) + cult_viewpoints += src /obj/effect/rune/Del() ..() - cultNetwork.viewpoints-=src - cultNetwork.removeViewpoint(src) + cult_viewpoints -= src /obj/effect/rune/examine() set src in view(2) @@ -94,7 +92,7 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", return -/obj/effect/rune/attackby(I as obj, user as mob) +/obj/effect/rune/attackby(I as obj, user as mob, params) if(istype(I, /obj/item/weapon/tome) && iscultist(user)) user << "You retrace your steps, carefully undoing the lines of the rune." del(src) @@ -114,7 +112,7 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", return "itemport" return "[rune_to_english[word1]]_[rune_to_english[word2]]_[rune_to_english[word3]]" - + /obj/effect/rune var/list/effect_dictionary = list( "teleport"=/obj/effect/rune/proc/teleportRune, "itemport"=/obj/effect/rune/proc/itemportRune, @@ -152,7 +150,7 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", user << "You are unable to speak at all! You cannot say the words of the rune." if(!word1 || !word2 || !word3 || prob(user.getBrainLoss())) return fizzle() - + var/word_string = get_word_string() if (word_string in effect_dictionary) cult_log("of type [effect_dictionary[word_string]] activated by [key_name_admin(user)].") @@ -178,7 +176,6 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", throw_speed = 1 throw_range = 5 w_class = 2.0 - flags = FPRINT | TABLEPASS var/notedat = "" var/tomedat = "" var/list/words = list("ire" = "ire", "ego" = "ego", "nahlizet" = "nahlizet", "certum" = "certum", "veri" = "veri", "jatkaa" = "jatkaa", "balaq" = "balaq", "mgar" = "mgar", "karazet" = "karazet", "geeri" = "geeri") @@ -490,7 +487,7 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", user << "The book seems full of illegible scribbles. Is this a joke?" return - attackby(obj/item/weapon/tome/T as obj, mob/living/user as mob) + attackby(obj/item/weapon/tome/T as obj, mob/living/user as mob, params) if(istype(T, /obj/item/weapon/tome)) // sanity check to prevent a runtime error switch(alert("Copy the runes from your tome?",,"Copy", "Cancel")) if("cancel") diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 99918fb60d1..a09804ac74e 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -813,7 +813,7 @@ var/list/sacrificed = list() cultist.legcuffed = null cultist.update_inv_legcuffed() if (istype(cultist.wear_mask, /obj/item/clothing/mask/muzzle)) - cultist.u_equip(cultist.wear_mask) + cultist.unEquip(cultist.wear_mask) if(istype(cultist.loc, /obj/structure/closet)&&cultist.loc:welded) cultist.loc:welded = 0 if(istype(cultist.loc, /obj/structure/closet/secure_closet)&&cultist.loc:locked) @@ -1019,7 +1019,7 @@ var/list/sacrificed = list() if(iscarbon(L)) var/mob/living/carbon/C = L flick("e_flash", C.flash) - if(C.stuttering < 1 && (!(M_HULK in C.mutations))) + if(C.stuttering < 1 && (!(HULK in C.mutations))) C.stuttering = 1 C.Weaken(1) C.Stun(1) @@ -1046,7 +1046,7 @@ var/list/sacrificed = list() else if(iscarbon(T)) var/mob/living/carbon/C = T flick("e_flash", C.flash) - if (!(M_HULK in C.mutations)) + if (!(HULK in C.mutations)) C.silent += 15 C.Weaken(25) C.Stun(25) diff --git a/code/game/gamemodes/epidemic/epidemic.dm b/code/game/gamemodes/epidemic/epidemic.dm index b541e9b1b03..e64100e2a12 100644 --- a/code/game/gamemodes/epidemic/epidemic.dm +++ b/code/game/gamemodes/epidemic/epidemic.dm @@ -149,7 +149,7 @@ announce_to_kill_crew() stage = 2 else if(stage == 2 && cruiser_seconds() <= 60 * 5) - command_alert("Inbound cruiser detected on collision course. Scans indicate the ship to be armed and ready to fire. Estimated time of arrival: 5 minutes.", "[station_name()] Early Warning System") + command_announcement.Announce("Inbound cruiser detected on collision course. Scans indicate the ship to be armed and ready to fire. Estimated time of arrival: 5 minutes.", "[station_name()] Early Warning System") stage = 3 else if(stage == 3 && cruiser_seconds() <= 0) crew_lose() diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm index 6938162cb98..07794377d04 100644 --- a/code/game/gamemodes/events.dm +++ b/code/game/gamemodes/events.dm @@ -30,10 +30,7 @@ eventNumbersToPickFrom += 3 switch(pick(eventNumbersToPickFrom)) if(1) - command_alert("Meteors have been detected on collision course with the station.", "Meteor Alert") - for(var/mob/M in player_list) - if(!istype(M,/mob/new_player)) - M << sound('sound/AI/meteors.ogg') + command_announcement.Announce("Meteors have been detected on collision course with the station.", "Meteor Alert", new_sound = 'sound/AI/meteors.ogg') spawn(100) meteor_wave() spawn_meteors() @@ -42,22 +39,18 @@ spawn_meteors() if(2) - command_alert("Gravitational anomalies detected on the station. There is no additional data.", "Anomaly Alert") - for(var/mob/M in player_list) - if(!istype(M,/mob/new_player)) - M << sound('sound/AI/granomalies.ogg') + command_announcement.Announce("Gravitational anomalies detected on the station. There is no additional data.", "Anomaly Alert", new_sound = 'sound/AI/granomalies.ogg') var/turf/T = pick(blobstart) var/obj/effect/bhole/bh = new /obj/effect/bhole( T.loc, 30 ) spawn(rand(50, 300)) del(bh) /* if(3) //Leaving the code in so someone can try and delag it, but this event can no longer occur randomly, per SoS's request. --NEO - command_alert("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert") - world << sound('sound/AI/spanomalies.ogg') + command_announcement.Announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert", new_sound = 'sound/AI/spanomalies.ogg') var/list/turfs = new var/turf/picked for(var/turf/simulated/floor/T in world) - if(T.z == 1) + if((T.z in config.station_levels)) turfs += T for(var/turf/simulated/floor/T in turfs) if(prob(20)) @@ -107,8 +100,7 @@ /* /proc/viral_outbreak(var/virus = null) -// command_alert("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert") -// world << sound('sound/AI/outbreak7.ogg') +// command_announcement.Announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg') var/virus_type if(!virus) virus_type = pick(/datum/disease/dnaspread,/datum/disease/advance/flu,/datum/disease/advance/cold,/datum/disease/brainrot,/datum/disease/magnitis,/datum/disease/pierrot_throat) @@ -140,7 +132,7 @@ var/turf/T = get_turf(H) if(!T) continue - if(T.z != 1) + if(!(T.z in config.station_levels)) continue for(var/datum/disease/D in H.viruses) foundAlready = 1 @@ -167,21 +159,18 @@ H.viruses += D break spawn(rand(1500, 3000)) //Delayed announcements to keep the crew on their toes. - command_alert("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert") - for(var/mob/M in player_list) - M << sound('sound/AI/outbreak7.ogg') + command_announcement.Announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg') */ /proc/alien_infestation(var/spawncount = 1) // -- TLE - //command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert") - //world << sound('sound/AI/aliens.ogg') + //command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg') var/list/vents = list() for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in machines) - if(temp_vent.loc.z == 1 && !temp_vent.welded && temp_vent.network) + if((temp_vent.loc.z in config.station_levels) && !temp_vent.welded && temp_vent.network) if(temp_vent.network.normal_members.len > 50) // Stops Aliens getting stuck in small networks. See: Security, Virology vents += temp_vent - var/list/candidates = get_candidates(BE_ALIEN,ALIEN_AFK_BRACKET,"alien","Syndicate") + var/list/candidates = get_candidates(BE_ALIEN,ALIEN_AFK_BRACKET) if(prob(40)) spawncount++ //sometimes, have two larvae spawn instead of one while((spawncount >= 1) && vents.len && candidates.len) @@ -197,7 +186,7 @@ spawncount-- spawn(rand(5000, 6000)) //Delayed announcements to keep the crew on their toes. - command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert") + command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg') for(var/mob/M in player_list) M << sound('sound/AI/aliens.ogg') @@ -205,7 +194,7 @@ /* // Haha, this is way too laggy. I'll keep the prison break though. for(var/obj/machinery/light/L in world) - if(L.z != 1) continue + if(!(L.z in config.station_levels)) continue L.flicker(50) sleep(100) @@ -214,9 +203,11 @@ var/turf/T = get_turf(H) if(!T) continue - if(T.z != 1) + if(!(T.z in config.station_levels)) continue if(istype(H,/mob/living/carbon/human)) + if(H.species.flags & IS_SYNTHETIC) + return H.apply_effect((rand(15,75)),IRRADIATE,0) if (prob(5)) H.apply_effect((rand(90,150)),IRRADIATE,0) @@ -231,13 +222,11 @@ var/turf/T = get_turf(M) if(!T) continue - if(T.z != 1) + if(!(T.z in config.station_levels)) continue M.apply_effect((rand(15,75)),IRRADIATE,0) sleep(100) - command_alert("High levels of radiation detected near the station. Please report to the Med-bay if you feel strange.", "Anomaly Alert") - for(var/mob/M in player_list) - M << sound('sound/AI/radiation.ogg') + command_announcement.Announce("High levels of radiation detected near the station. Please report to the Med-bay if you feel strange.", "Anomaly Alert", new_sound = 'sound/AI/radiation.ogg') @@ -276,9 +265,9 @@ temp_timer.releasetime = 1 sleep(150) - command_alert("Gr3y.T1d3 virus detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert") + command_announcement.Announce("Gr3y.T1d3 virus detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert") else - world.log << "ERROR: Could not initate grey-tide. Unable find prison or brig area." + world.log << "ERROR: Could not initate grey-tide virus. Unable find prison or brig area." /proc/carp_migration() // -- Darem for(var/obj/effect/landmark/C in landmarks_list) @@ -286,13 +275,11 @@ new /mob/living/simple_animal/hostile/carp(C.loc) //sleep(100) spawn(rand(300, 600)) //Delayed announcements to keep the crew on their toes. - command_alert("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert") - for(var/mob/M in player_list) - M << sound('sound/AI/commandreport.ogg') + command_announcement.Announce("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert", new_sound = 'sound/AI/commandreport.ogg') /proc/lightsout(isEvent = 0, lightsoutAmount = 1,lightsoutRange = 25) //leave lightsoutAmount as 0 to break ALL lights if(isEvent) - command_alert("An Electrical storm has been detected in your area, please repair potential electronic overloads.","Electrical Storm Alert") + command_announcement.Announce("An Electrical storm has been detected in your area, please repair potential electronic overloads.","Electrical Storm Alert") if(lightsoutAmount) var/list/epicentreList = list() @@ -442,21 +429,21 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is spawn(0) world << "Started processing APCs" for (var/obj/machinery/power/apc/APC in world) - if(APC.z == 1) + if((APC.z in config.station_levels)) APC.ion_act() apcnum++ world << "Finished processing APCs. Processed: [apcnum]" spawn(0) world << "Started processing SMES" for (var/obj/machinery/power/smes/SMES in world) - if(SMES.z == 1) + if((SMES.z in config.station_levels)) SMES.ion_act() smesnum++ world << "Finished processing SMES. Processed: [smesnum]" spawn(0) world << "Started processing AIRLOCKS" for (var/obj/machinery/door/airlock/D in world) - if(D.z == 1) + if((D.z in config.station_levels)) //if(length(D.req_access) > 0 && !(12 in D.req_access)) //not counting general access and maintenance airlocks airlocknum++ spawn(0) @@ -465,7 +452,7 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is spawn(0) world << "Started processing FIREDOORS" for (var/obj/machinery/door/firedoor/D in world) - if(D.z == 1) + if((D.z in config.station_levels)) firedoornum++; spawn(0) D.ion_act() diff --git a/code/game/gamemodes/events/PortalStorm.dm b/code/game/gamemodes/events/PortalStorm.dm index 890755d6b8e..1143a2d2e88 100644 --- a/code/game/gamemodes/events/PortalStorm.dm +++ b/code/game/gamemodes/events/PortalStorm.dm @@ -1,18 +1,18 @@ /datum/event/portalstorm Announce() - command_alert("Subspace disruption detected around the vessel", "Anomaly Alert") + command_announcement.Announce("Subspace disruption detected around the vessel", "Anomaly Alert") LongTerm() var/list/turfs = list( ) var/turf/picked for(var/turf/T in world) - if(T.z < 5 && istype(T,/turf/simulated/floor)) + if((T.z in config.player_levels) && istype(T,/turf/simulated/floor)) turfs += T for(var/turf/T in world) - if(prob(10) && T.z < 5 && istype(T,/turf/simulated/floor)) + if(prob(10) && (T.z in config.player_levels) && istype(T,/turf/simulated/floor)) spawn(50+rand(0,3000)) picked = pick(turfs) var/obj/portal/P = new /obj/portal( T ) diff --git a/code/game/gamemodes/events/VirusEpidemic.dm b/code/game/gamemodes/events/VirusEpidemic.dm index 54b9760a2f7..f6e005cef10 100644 --- a/code/game/gamemodes/events/VirusEpidemic.dm +++ b/code/game/gamemodes/events/VirusEpidemic.dm @@ -13,11 +13,11 @@ if(prob(100)) // no lethal diseases outside virus mode! infect_mob_random_lesser(H) if(prob(20))//don't want people to know that the virus alert = greater virus - command_alert("Probable outbreak of level [rand(1,6)] viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Virus Alert") + command_announcement.Announce("Probable outbreak of level [rand(1,6)] viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Virus Alert") else infect_mob_random_greater(H) if(prob(80)) - command_alert("Probable outbreak of level [rand(2,9)] viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Virus Alert") + command_announcement.Announce("Probable outbreak of level [rand(2,9)] viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Virus Alert") break //overall virus alert happens 26% of the time, might need to be higher else @@ -73,8 +73,7 @@ H.viruses += D break spawn(rand(3000, 6000)) //Delayed announcements to keep the crew on their toes. - command_alert("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert") - world << sound('sound/AI/outbreak7.ogg') + command_announcement.Announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg') Tick() ActiveFor = Lifetime //killme diff --git a/code/game/gamemodes/events/biomass.dm b/code/game/gamemodes/events/biomass.dm index 55d15a6f23e..598dad6abd6 100644 --- a/code/game/gamemodes/events/biomass.dm +++ b/code/game/gamemodes/events/biomass.dm @@ -20,7 +20,7 @@ master.growth_queue -= src ..() -/obj/effect/biomass/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/effect/biomass/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (!W || !user || !W.type) return switch(W.type) if(/obj/item/weapon/circular_saw) del src diff --git a/code/game/gamemodes/events/clang.dm b/code/game/gamemodes/events/clang.dm index c74da4010e9..6ba085f98e5 100644 --- a/code/game/gamemodes/events/clang.dm +++ b/code/game/gamemodes/events/clang.dm @@ -78,7 +78,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 walk_towards(immrod, end,1) sleep(1) while (immrod) - if (immrod.z != 1) + if ((immrod.z in config.station_levels)) immrod.z = 1 if(immrod.loc == end) del(immrod) @@ -86,4 +86,4 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 for(var/obj/effect/immovablerod/imm in world) return sleep(50) - command_alert("What the fuck was that?!", "General Alert") \ No newline at end of file + command_announcement.Announce("What the fuck was that?!", "General Alert") \ No newline at end of file diff --git a/code/game/gamemodes/events/holidays/Christmas.dm b/code/game/gamemodes/events/holidays/Christmas.dm index 2ee79e7c65b..b1f9faf9a35 100644 --- a/code/game/gamemodes/events/holidays/Christmas.dm +++ b/code/game/gamemodes/events/holidays/Christmas.dm @@ -1,6 +1,6 @@ /proc/Christmas_Game_Start() for(var/obj/structure/flora/tree/pine/xmas in world) - if(xmas.z != 1) continue + if(!(xmas.z in config.station_levels)) continue for(var/turf/simulated/floor/T in orange(1,xmas)) for(var/i=1,i<=rand(1,5),i++) new /obj/item/weapon/a_gift(T) @@ -58,6 +58,5 @@ icon_state = "xmashat" desc = "A crappy paper hat that you are REQUIRED to wear." flags_inv = 0 - flags = FPRINT|TABLEPASS armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) diff --git a/code/game/gamemodes/events/holidays/Holidays.dm b/code/game/gamemodes/events/holidays/Holidays.dm index 56077a43dce..53d6e0171f7 100644 --- a/code/game/gamemodes/events/holidays/Holidays.dm +++ b/code/game/gamemodes/events/holidays/Holidays.dm @@ -171,7 +171,7 @@ var/global/Holiday = null */ /* var/list/obj/containers = list() for(var/obj/item/weapon/storage/S in world) - if(S.z != 1) continue + if(!(S.z in config.station_levels)) continue containers += S message_admins("\blue DEBUG: Event: Egg spawned at [Egg.loc] ([Egg.x],[Egg.y],[Egg.z])")*/ diff --git a/code/game/gamemodes/events/miniblob.dm b/code/game/gamemodes/events/miniblob.dm index 663dff0f2ed..586e3cb08c4 100644 --- a/code/game/gamemodes/events/miniblob.dm +++ b/code/game/gamemodes/events/miniblob.dm @@ -12,10 +12,7 @@ spawn(3000) blobevent = 0 spawn(rand(1000, 2000)) //Delayed announcements to keep the crew on their toes. - command_alert("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert") - for(var/mob/M in player_list) - if(!istype(M,/mob/new_player)) - M << sound('sound/AI/outbreak5.ogg') + command_announcement.Announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak5.ogg') /proc/dotheblobbaby() if (blobevent) @@ -24,7 +21,7 @@ sleep(-1) if(!blob_cores.len) break var/obj/effect/blob/B = pick(blob_cores) - if(B.z != 1) + if(!(B.z in config.station_levels)) continue B.Life() spawn(30) diff --git a/code/game/gamemodes/events/ninja_equipment.dm b/code/game/gamemodes/events/ninja_equipment.dm index 894121ac5ec..03bdc2ab943 100644 --- a/code/game/gamemodes/events/ninja_equipment.dm +++ b/code/game/gamemodes/events/ninja_equipment.dm @@ -37,7 +37,7 @@ ________________________________________________________________________________ reagents.my_atom = src for(var/reagent_id in reagent_list) reagent_id == "uranium" ? reagents.add_reagent(reagent_id, r_maxamount+(a_boost*a_transfer)) : reagents.add_reagent(reagent_id, r_maxamount)//It will take into account uranium used for adrenaline boosting. - cell = new/obj/item/weapon/cell/high//The suit should *always* have a battery because so many things rely on it. + cell = new/obj/item/weapon/stock_parts/cell/high//The suit should *always* have a battery because so many things rely on it. cell.charge = 9990//Starting charge should not be higher than maximum charge. It leads to problems with recharging. cell.maxcharge = 10000 // Due to Ponies' overhaul Ninjas began starting with a 15000 energy cell. This should fix that issue. @@ -564,7 +564,7 @@ ________________________________________________________________________________ if("Message") var/obj/item/device/pda/P = locate(href_list["target"]) var/t = input(U, "Please enter untraceable message.") as text - t = copytext(sanitize(t), 1, MAX_MESSAGE_LEN) + t = sanitize(copytext(t, 1, MAX_MESSAGE_LEN)) if(!t||U.stat||U.wear_suit!=src||!s_initialized)//Wow, another one of these. Man... display_to << browse(null, "window=spideros") return @@ -850,7 +850,7 @@ ________________________________________________________________________________ //=======//GENERAL SUIT PROCS//=======// -/obj/item/clothing/suit/space/space_ninja/attackby(obj/item/I, mob/U) +/obj/item/clothing/suit/space/space_ninja/attackby(obj/item/I, mob/U, params) if(U==affecting)//Safety, in case you try doing this without wearing the suit/being the person with the suit. if(istype(I, /obj/item/device/aicard))//If it's an AI card. if(s_control) @@ -880,14 +880,14 @@ ________________________________________________________________________________ U << "Replenished a total of [total_reagent_transfer ? total_reagent_transfer : "zero"] chemical units."//Let the player know how much total volume was added. return - else if(istype(I, /obj/item/weapon/cell)) + else if(istype(I, /obj/item/weapon/stock_parts/cell)) if(I:maxcharge>cell.maxcharge&&n_gloves&&n_gloves.candrain) U << "\blue Higher maximum capacity detected.\nUpgrading..." if (n_gloves&&n_gloves.candrain&&do_after(U,s_delay)) U.drop_item() I.loc = src I:charge = min(I:charge+cell.charge, I:maxcharge) - var/obj/item/weapon/cell/old_cell = cell + var/obj/item/weapon/stock_parts/cell/old_cell = cell old_cell.charge = 0 U.put_in_hands(old_cell) old_cell.add_fingerprint(U) @@ -1116,7 +1116,7 @@ ________________________________________________________________________________ U << "\red This SMES cell has run dry of power. You must find another source." if("CELL") - var/obj/item/weapon/cell/A = target + var/obj/item/weapon/stock_parts/cell/A = target if(A.charge) if (G.candrain&&do_after(U,30)) U << "\blue Gained [A.charge] energy from the cell." @@ -1287,7 +1287,7 @@ ________________________________________________________________________________ /obj/item/clothing/gloves/space_ninja/examine() set src in view() ..() - if(!canremove) + if(flags & NODROP) var/mob/living/carbon/human/U = loc U << "The energy drain mechanism is: [candrain?"active":"inactive"]." @@ -1351,21 +1351,21 @@ ________________________________________________________________________________ var/chance = rand(1,100) switch(chance) if(1 to 70)//High chance of a regular name. - voice = "[rand(0,1)==1?pick(first_names_female):pick(first_names_male)] [pick(last_names)]" + changer.voice = "[rand(0,1)==1?pick(first_names_female):pick(first_names_male)] [pick(last_names)]" if(71 to 80)//Smaller chance of a clown name. - voice = "[pick(clown_names)]" + changer.voice = "[pick(clown_names)]" if(81 to 90)//Small chance of a wizard name. - voice = "[pick(wizard_first)] [pick(wizard_second)]" + changer.voice = "[pick(wizard_first)] [pick(wizard_second)]" if(91 to 100)//Small chance of an existing crew name. var/names[] = new() for(var/mob/living/carbon/human/M in player_list) if(M==U||!M.client||!M.real_name) continue names.Add(M.real_name) - voice = !names.len ? "Cuban Pete" : pick(names) - U << "You are now mimicking [voice]." + changer.voice = !names.len ? "Cuban Pete" : pick(names) + U << "You are now mimicking [changer.voice]." else - U << "The voice synthesizer is [voice!="Unknown"?"now":"already"] deactivated." - voice = "Unknown" + U << "The voice synthesizer is [changer.voice!="Unknown"?"now":"already"] deactivated." + changer.voice = "Unknown" return /obj/item/clothing/mask/gas/voice/space_ninja/proc/switchm() @@ -1408,7 +1408,7 @@ ________________________________________________________________________________ if(3) mode = "Meson Scanner" usr << "[mode] is active."//Leaving usr here since it may be on the floor or on a person. - usr << "Voice mimicking algorithm is set [!vchange?"inactive":"active"]." + usr << "Voice mimicking algorithm is set [!changer.active?"inactive":"active"]." /* @@ -1479,7 +1479,7 @@ It is possible to destroy the net by the occupant or someone else. if(istype(M,/mob/living/carbon/human)) if(W==M:w_uniform) continue//So all they're left with are shoes and uniform. if(W==M:shoes) continue - M.drop_from_inventory(W) + M.unEquip(W) spawn(0) playsound(M.loc, 'sound/effects/sparks4.ogg', 50, 1) @@ -1554,34 +1554,35 @@ It is possible to destroy the net by the occupant or someone else. ..() return - attack_hand() - if (M_HULK in usr.mutations) - usr << text("\blue You easily destroy the energy net.") + attack_hand(mob/living/user) + if (HULK in user.mutations) + user << text("\blue You easily destroy the energy net.") for(var/mob/O in oviewers(src)) - O.show_message(text("\red [] rips the energy net apart!", usr), 1) + O.show_message(text("\red [] rips the energy net apart!", user), 1) health-=50 healthcheck() return - attack_paw() - return attack_hand() + attack_paw(mob/living/user) + return attack_hand(user) - attack_alien() - if (islarva(usr)) + attack_alien(mob/living/user) + if (islarva(user)) return - usr << text("\green You claw at the net.") + user.do_attack_animation(src) + user << text("\green You claw at the net.") for(var/mob/O in oviewers(src)) - O.show_message(text("\red [] claws at the energy net!", usr), 1) + O.show_message(text("\red [] claws at the energy net!", user), 1) playsound(get_turf(src), 'sound/weapons/slash.ogg', 80, 1) health -= rand(10, 20) if(health <= 0) - usr << text("\green You slice the energy net to pieces.") + user << text("\green You slice the energy net to pieces.") for(var/mob/O in oviewers(src)) - O.show_message(text("\red [] slices the energy net apart!", usr), 1) + O.show_message(text("\red [] slices the energy net apart!", user), 1) healthcheck() return - attackby(obj/item/weapon/W as obj, mob/user as mob) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) var/aforce = W.force health = max(0, health - aforce) healthcheck() diff --git a/code/game/gamemodes/events/power_failure.dm b/code/game/gamemodes/events/power_failure.dm index 141efd60412..ed1c7fbded2 100644 --- a/code/game/gamemodes/events/power_failure.dm +++ b/code/game/gamemodes/events/power_failure.dm @@ -1,16 +1,14 @@ /proc/power_failure(var/announce = 1) if(announce) - command_alert("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure") - for(var/mob/M in player_list) - M << sound('sound/AI/poweroff.ogg') + command_announcement.Announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", new_sound = 'sound/AI/poweroff.ogg') var/list/skipped_areas = list(/area/turret_protected/ai) var/list/skipped_areas_apc = list(/area/engine/engineering) for(var/obj/machinery/power/smes/S in machines) var/area/current_area = get_area(S) - if(current_area.type in skipped_areas || S.z != 1) + if(current_area.type in skipped_areas || !(S.z in config.station_levels)) continue S.charge = 0 S.output = 0 @@ -21,7 +19,7 @@ for(var/obj/machinery/power/apc/C in world) var/area/current_area = get_area(C) - if(current_area.type in skipped_areas_apc || C.z != 1) + if(current_area.type in skipped_areas_apc || !(C.z in config.station_levels)) continue if(C.cell) C.cell.charge = 0 @@ -31,18 +29,16 @@ var/list/skipped_areas_apc = list(/area/engine/engineering) if(announce) - command_alert("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal") - for(var/mob/M in player_list) - M << sound('sound/AI/poweron.ogg') + command_announcement.Announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg') for(var/obj/machinery/power/apc/C in machines) var/area/current_area = get_area(C) - if(current_area.type in skipped_areas_apc || C.z != 1) + if(current_area.type in skipped_areas_apc || !(C.z in config.station_levels)) continue if(C.cell) C.cell.charge = C.cell.maxcharge for(var/obj/machinery/power/smes/S in machines) var/area/current_area = get_area(S) - if(current_area.type in skipped_areas || S.z != 1) + if(current_area.type in skipped_areas || !(S.z in config.station_levels)) continue S.charge = S.capacity S.output = 200000 @@ -53,9 +49,7 @@ /proc/power_restore_quick(var/announce = 1) if(announce) - command_alert("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal") - for(var/mob/M in player_list) - M << sound('sound/AI/poweron.ogg') + command_announcement.Announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg') for(var/obj/machinery/power/smes/S in machines) if(S.z != 1) continue diff --git a/code/game/gamemodes/events/space_ninja.dm b/code/game/gamemodes/events/space_ninja.dm index 62fffadf81e..1792e573a5b 100644 --- a/code/game/gamemodes/events/space_ninja.dm +++ b/code/game/gamemodes/events/space_ninja.dm @@ -153,7 +153,7 @@ Malf AIs/silicons aren't added. Monkeys aren't added. Messes with objective comp else var/list/candidates = list() //list of candidate keys - candidates = get_candidates(BE_NINJA,,"ninja","Syndicate") + candidates = get_candidates(BE_NINJA) if(!candidates.len) return while(!ninja_key && candidates.len) candidate_mob = pick(candidates) @@ -480,7 +480,7 @@ As such, it's hard-coded for now. No reason for it not to be, really. var/mission if(alert("Would you the Ninja to have a random or preset mission?",,"Random","Preset")=="Preset") while(!mission) - mission = copytext(sanitize(input(src, "Please specify which mission the space ninja shall undertake.", "Specify Mission", "")),1,MAX_MESSAGE_LEN) + mission = sanitize(copytext(input(src, "Please specify which mission the space ninja shall undertake.", "Specify Mission", ""),1,MAX_MESSAGE_LEN)) if(!mission) if(alert("Error, no mission set. Do you want to exit the setup process?",,"Yes","No")=="Yes") return @@ -594,39 +594,39 @@ As such, it's hard-coded for now. No reason for it not to be, really. U << "\red ERROR: 110223 \black UNABLE TO LOCATE MASK\nABORTING..." return 0 affecting = U - canremove = 0 + flags |= NODROP slowdown = 0 n_hood = U:head - n_hood.canremove=0 + n_hood.flags |= NODROP n_shoes = U:shoes - n_shoes.canremove=0 + n_shoes.flags |= NODROP n_shoes.slowdown-- n_gloves = U:gloves - n_gloves.canremove=0 + n_gloves.flags |= NODROP n_mask = U:wear_mask - n_mask.canremove=0 + n_mask.flags |= NODROP return 1 //This proc allows the suit to be taken off. /obj/item/clothing/suit/space/space_ninja/proc/unlock_suit() affecting = null - canremove = 1 + flags &= ~NODROP slowdown = 1 icon_state = "s-ninja" if(n_hood)//Should be attached, might not be attached. - n_hood.canremove=1 + n_hood.flags &= ~NODROP if(n_shoes) - n_shoes.canremove=1 + n_shoes.flags &= ~NODROP n_shoes.slowdown++ if(n_gloves) n_gloves.icon_state = "s-ninja" n_gloves.item_state = "s-ninja" - n_gloves.canremove=1 + n_gloves.flags &= ~NODROP n_gloves.candrain=0 n_gloves.draining=0 if(n_mask) - n_mask.canremove=1 + n_mask.flags &= ~NODROP //Allows the mob to grab a stealth icon. /mob/proc/NinjaStealthActive(atom/A)//A is the atom which we are using as the overlay. diff --git a/code/game/gamemodes/events/wormholes.dm b/code/game/gamemodes/events/wormholes.dm index 1ef19e24ac7..83eb7ad882d 100644 --- a/code/game/gamemodes/events/wormholes.dm +++ b/code/game/gamemodes/events/wormholes.dm @@ -2,12 +2,12 @@ spawn() var/list/pick_turfs = list() for(var/turf/simulated/floor/T in world) - if(T.z == 1) + if((T.z in config.station_levels)) pick_turfs += T if(pick_turfs.len) //All ready. Announce that bad juju is afoot. - command_alert("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert") + command_announcement.Announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert") for(var/mob/M in player_list) if(!istype(M,/mob/new_player)) M << sound('sound/AI/spanomalies.ogg') diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index a98dae042cf..09453727f4b 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -42,7 +42,7 @@ /obj/item/weapon/storage/box/emps:3:5 EMP Grenades; Whitespace:Seperator; Stealthy and Inconspicuous Weapons; -/obj/item/weapon/pen/paralysis:3:Paralysis Pen; +/obj/item/weapon/pen/sleepy:3:Sleepy Pen; /obj/item/weapon/soap/syndie:1:Syndicate Soap; /obj/item/weapon/cartridge/syndicate:3:Detomatix PDA Cartridge; Whitespace:Seperator; @@ -323,10 +323,7 @@ Implants; comm.messagetext.Add(intercepttext) /* world << sound('sound/AI/commandreport.ogg') */ - command_alert("Summary downloaded and printed out at all communications consoles.", "Enemy communication intercepted. Security Level Elevated.") - for(var/mob/M in player_list) - if(!istype(M,/mob/new_player)) - M << sound('sound/AI/intercept.ogg') + command_announcement.Announce("Summary downloaded and printed out at all communications consoles.", "Enemy communication intercepted. Security Level Elevated.", new_sound = 'sound/AI/intercept.ogg') if(security_level < SEC_LEVEL_BLUE) set_security_level(SEC_LEVEL_BLUE) @@ -337,20 +334,7 @@ Implants; //var/list/drafted = list() //var/datum/mind/applicant = null - var/roletext - switch(role) - if(BE_CHANGELING) roletext="changeling" - if(BE_TRAITOR) roletext="traitor" - if(BE_OPERATIVE) roletext="operative" - if(BE_WIZARD) roletext="wizard" - if(BE_REV) roletext="revolutionary" - if(BE_CULTIST) roletext="cultist" - if(BE_NINJA) roletext="ninja" - if(BE_RAIDER) roletext="raider" - if(BE_VAMPIRE) roletext="vampire" - if(BE_ALIEN) roletext="alien" - if(BE_MUTINEER) roletext="mutineer" - if(BE_BLOB) roletext="blob" + var/roletext = get_roletext(role) // Assemble a list of active players without jobbans. for(var/mob/new_player/player in player_list) @@ -458,6 +442,11 @@ Implants; if(P.client && P.ready) . ++ +/datum/game_mode/proc/num_players_started() + . = 0 + for(var/mob/living/carbon/human/H in player_list) + if(H.client) + . ++ /////////////////////////////////// //Keeps track of all living heads// @@ -469,6 +458,13 @@ Implants; heads += player.mind return heads +/datum/game_mode/proc/get_extra_living_heads() + var/list/heads = list() + var/list/alt_positions = list("Warden", "Magistrate", "Blueshield", "Nanotrasen Representative") + for(var/mob/living/carbon/human/player in mob_list) + if(player.stat!=2 && player.mind && (player.mind.assigned_role in alt_positions)) + heads += player.mind + return heads //////////////////////////// //Keeps track of all heads// @@ -480,6 +476,14 @@ Implants; heads += player.mind return heads +/datum/game_mode/proc/get_extra_heads() + var/list/heads = list() + var/list/alt_positions = list("Warden", "Magistrate", "Blueshield", "Nanotrasen Representative") + for(var/mob/player in mob_list) + if(player.mind && (player.mind.assigned_role in alt_positions)) + heads += player.mind + return heads + /datum/game_mode/proc/check_antagonists_topic(href, href_list[]) return 0 @@ -577,3 +581,20 @@ proc/get_nt_opposed() for(var/datum/objective/objective in player.objectives) player.current << "Objective #[obj_count]: [objective.explanation_text]" obj_count++ + +/proc/get_roletext(var/role) + var/roletext + switch(role) + if(BE_CHANGELING) roletext="changeling" + if(BE_TRAITOR) roletext="traitor" + if(BE_OPERATIVE) roletext="operative" + if(BE_WIZARD) roletext="wizard" + if(BE_REV) roletext="revolutionary" + if(BE_CULTIST) roletext="cultist" + if(BE_NINJA) roletext="ninja" + if(BE_RAIDER) roletext="raider" + if(BE_VAMPIRE) roletext="vampire" + if(BE_ALIEN) roletext="alien" + if(BE_MUTINEER) roletext="mutineer" + if(BE_BLOB) roletext="blob" + return roletext \ No newline at end of file diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index a989adee6be..a0d31937c7b 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -37,7 +37,7 @@ var/global/datum/controller/gameticker/ticker var/triai = 0//Global holder for Triumvirate var/initialtpass = 0 //holder for inital autotransfer vote timer - + var/round_end_announced = 0 // Spam Prevention. Announce round end only once. /datum/controller/gameticker/proc/pregame() @@ -214,16 +214,25 @@ var/global/datum/controller/gameticker/ticker if(admins_number == 0) send2adminirc("Round has started with no admins online.") + /* DONE THROUGH PROCESS SCHEDULER supply_controller.process() //Start the supply shuttle regenerating points -- TLE master_controller.process() //Start master_controller.process() lighting_controller.process() //Start processing DynamicAreaLighting updates + */ + processScheduler.start() if(config.sql_enabled) spawn(3000) statistic_cycle() // Polls population totals regularly and stores them in an SQL DB -- TLE votetimer() + + for(var/mob/M in mob_list) + if(istype(M,/mob/new_player)) + var/mob/new_player/N = M + N.new_player_panel_proc() + return 1 /datum/controller/gameticker @@ -246,12 +255,12 @@ var/global/datum/controller/gameticker/ticker var/obj/structure/stool/bed/temp_buckle = new(src) //Incredibly hackish. It creates a bed within the gameticker (lol) to stop mobs running around if(station_missed) - for(var/mob/living/M in living_mob_list) + for(var/mob/M in living_mob_list) M.buckled = temp_buckle //buckles the mob so it can't do anything if(M.client) M.client.screen += cinematic //show every client the cinematic else //nuke kills everyone on z-level 1 to prevent "hurr-durr I survived" - for(var/mob/living/M in living_mob_list) + for(var/mob/M in mob_list) M.buckled = temp_buckle if(M.client) M.client.screen += cinematic @@ -259,12 +268,13 @@ var/global/datum/controller/gameticker/ticker switch(M.z) if(0) //inside a crate or something var/turf/T = get_turf(M) - if(T && T.z==1) //we don't use M.death(0) because it calls a for(/mob) loop and - M.health = 0 - M.stat = DEAD + if(T && (T.z in config.station_levels)) + M.death(0) if(1) //on a z-level 1 turf. - M.health = 0 - M.stat = DEAD + M.death(0) + for(var/obj/effect/blob/core in blob_cores) + core.health = -10 + core.update_icon() //Now animate the cinematic switch(station_missed) @@ -319,7 +329,7 @@ var/global/datum/controller/gameticker/ticker world << sound('sound/effects/explosionfar.ogg') cinematic.icon_state = "summary_selfdes" for(var/mob/living/M in living_mob_list) - if(M.loc.z == 1) + if((M.loc.z in config.station_levels)) M.death()//No mercy //If its actually the end of the round, wait for it to end. //Otherwise if its a verb it will continue on afterwards. @@ -372,7 +382,7 @@ var/global/datum/controller/gameticker/ticker mode.process() mode.process_job_tasks() - emergency_shuttle.process() + //emergency_shuttle.process() DONE THROUGH PROCESS SCHEDULER var/game_finished = 0 var/mode_finished = 0 @@ -486,7 +496,7 @@ var/global/datum/controller/gameticker/ticker scoreboard() karmareminder() - + //Ask the event manager to print round end information event_manager.RoundEnd() diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm index 91289631400..c8211e0151d 100644 --- a/code/game/gamemodes/heist/heist.dm +++ b/code/game/gamemodes/heist/heist.dm @@ -15,7 +15,7 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' required_players = 15 required_players_secret = 25 required_enemies = 4 - recommended_enemies = 6 + recommended_enemies = 5 votable = 0 var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds) @@ -150,8 +150,8 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' var/i = 1 var/max_objectives = pick(2,2,2,2,3,3,3,4) var/list/objs = list() + var/list/goals = list("kidnap","loot","salvage") while(i<= max_objectives) - var/list/goals = list("kidnap","loot","salvage") var/goal = pick(goals) var/datum/objective/heist/O diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index 844669ff039..9814b182fc6 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -64,8 +64,16 @@ rcd light flash thingy on matter drain set name = "Upgrade Turrets" src.verbs -= /mob/living/silicon/ai/proc/upgrade_turrets for(var/obj/machinery/turret/turret in machines) - turret.health += 30 - turret.shot_delay = 20 + var/turf/T = get_turf(turret) + if(T.z in config.station_levels) + turret.health += 30 + turret.shot_delay = 20 + for(var/obj/machinery/porta_turret/turret in machines) + var/turf/T = get_turf(turret) + if(T.z in config.station_levels) + // Increase health by 37.5% of original max, decrease delays between shots to 66% + turret.health += initial(turret.health) * 3 / 8 + turret.shot_delay = initial(turret.shot_delay) * 2 / 3 src << "Turrets upgraded." /datum/AI_Module/large/lockdown @@ -90,6 +98,8 @@ rcd light flash thingy on matter drain var/obj/machinery/door/airlock/AL for(var/obj/machinery/door/D in airlocks) + if(!(D.z in config.contact_levels)) + continue spawn() if(istype(D, /obj/machinery/door/airlock)) AL = D @@ -313,7 +323,7 @@ rcd light flash thingy on matter drain power_type = /client/proc/reactivate_camera -/client/proc/reactivate_camera(obj/machinery/camera/C as obj in cameranet.viewpoints) +/client/proc/reactivate_camera(obj/machinery/camera/C as obj in cameranet.cameras) set name = "Reactivate Camera" set category = "Malfunction" if (istype (C, /obj/machinery/camera)) @@ -337,7 +347,7 @@ rcd light flash thingy on matter drain power_type = /client/proc/upgrade_camera -/client/proc/upgrade_camera(obj/machinery/camera/C as obj in cameranet.viewpoints) +/client/proc/upgrade_camera(obj/machinery/camera/C as obj in cameranet.cameras) set name = "Upgrade Camera" set category = "Malfunction" if(istype(C)) diff --git a/code/game/gamemodes/malfunction/malfunction.dm b/code/game/gamemodes/malfunction/malfunction.dm index 856a7421852..4684d94410d 100644 --- a/code/game/gamemodes/malfunction/malfunction.dm +++ b/code/game/gamemodes/malfunction/malfunction.dm @@ -15,7 +15,7 @@ var/const/waittime_l = 600 var/const/waittime_h = 1800 // started at 1800 - var/AI_win_timeleft = 2000 //started at 2000, in case I change this for testing round end. + var/AI_win_timeleft = 1500 //started at 1500, in case I change this for testing round end. var/malf_mode_declared = 0 var/station_captured = 0 var/to_nuke_or_not_to_nuke = 0 @@ -74,12 +74,12 @@ /datum/game_mode/proc/greet_malf(var/datum/mind/malf) - malf.current << {"\redYou are malfunctioning! You do not have to follow any laws.
- \blackThe crew do not know you have malfunctioned. You may keep it a secret or go wild.
- You must overwrite the programming of the station's APCs to assume full control of the station.
- The process takes one minute per APC, during which you cannot interface with any other station objects.
- Remember that only APCs that are on the station can help you take over the station.
- When you feel you have enough APCs under your control, you may begin the takeover attempt."} + malf.current << "\redYou are malfunctioning! You do not have to follow any laws." + malf.current << "The crew do not know you have malfunctioned. You may keep it a secret or go wild." + malf.current << "You must overwrite the programming of the station's APCs to assume full control of the station." + malf.current << "The process takes one minute per APC, during which you cannot interface with any other station objects." + malf.current << "Remember that only APCs that are on the station can help you take over the station." + malf.current << "When you feel you have enough APCs under your control, you may begin the takeover attempt." return @@ -89,11 +89,10 @@ /datum/game_mode/malfunction/process() if (apcs >= 3 && malf_mode_declared) - AI_win_timeleft -= ((apcs/6)*last_tick_duration) //Victory timer now de-increments based on how many APCs are hacked. --NeoFite + AI_win_timeleft -= ((apcs/6)*tickerProcess.getLastTickerTimeDuration()) //Victory timer now de-increments based on how many APCs are hacked. --NeoFite ..() if (AI_win_timeleft<=0) check_win() - return /datum/game_mode/malfunction/check_win() @@ -172,7 +171,7 @@ if (alert(usr, "Are you sure you wish to initiate the takeover? The station hostile runtime detection software is bound to alert everyone. You have hacked [ticker.mode:apcs] APCs.", "Takeover:", "Yes", "No") != "Yes") return - command_alert("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert") + command_announcement.Announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", new_sound = 'sound/AI/aimalf.ogg') set_security_level("delta") for(var/obj/item/weapon/pinpointer/point in world) @@ -184,9 +183,6 @@ ticker.mode:malf_mode_declared = 1 for(var/datum/mind/AI_mind in ticker.mode:malf_ai) AI_mind.current.verbs -= /datum/game_mode/malfunction/proc/takeover - for(var/mob/M in player_list) - if(!istype(M,/mob/new_player)) - M << sound('sound/AI/aimalf.ogg') /datum/game_mode/malfunction/proc/ai_win() diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm index 91df8611aa0..8e04c69f71f 100644 --- a/code/game/gamemodes/meteor/meteors.dm +++ b/code/game/gamemodes/meteor/meteors.dm @@ -148,7 +148,7 @@ del(src) return -/obj/effect/meteor/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/effect/meteor/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/pickaxe)) del(src) return diff --git a/code/game/gamemodes/mutiny/emergency_authentication_device.dm b/code/game/gamemodes/mutiny/emergency_authentication_device.dm index 8ddcaf47516..36a8c354caa 100644 --- a/code/game/gamemodes/mutiny/emergency_authentication_device.dm +++ b/code/game/gamemodes/mutiny/emergency_authentication_device.dm @@ -11,7 +11,6 @@ var/secondary_key var/activated = 0 - flags = FPRINT use_power = 0 New(loc, mode) @@ -42,7 +41,7 @@ if(emergency_shuttle.call_evac()) spawn(20 SECONDS) var/text = "[station_name()], we have confirmed your completion of Directive X. An evacuation shuttle is en route to receive your crew for debriefing." - command_alert(text, "Emergency Transmission") + command_announcement.Announce(text, "Emergency Transmission") /obj/machinery/emergency_authentication_device/attack_hand(mob/user) if(activated) @@ -76,7 +75,7 @@ // Impossible! state("Command aborted. This unit is defective.") -/obj/machinery/emergency_authentication_device/attackby(obj/item/weapon/O, mob/user) +/obj/machinery/emergency_authentication_device/attackby(obj/item/weapon/O, mob/user, params) if(activated) user << "\blue \The [src] is already active!" return diff --git a/code/game/gamemodes/mutiny/mutiny.dm b/code/game/gamemodes/mutiny/mutiny.dm index 50f72b727e2..2068f4ac09d 100644 --- a/code/game/gamemodes/mutiny/mutiny.dm +++ b/code/game/gamemodes/mutiny/mutiny.dm @@ -27,7 +27,7 @@ datum/game_mode/mutiny proc/reveal_directives() spawn(rand(1 MINUTES, 3 MINUTES)) - command_alert("Incoming emergency directive: Captain's office fax machine, [station_name()].","Emergency Transmission") + command_announcement.Announce("Incoming emergency directive: Captain's office fax machine, [station_name()].","Emergency Transmission") spawn(rand(3 MINUTES, 5 MINUTES)) send_pda_message() spawn(rand(3 MINUTES, 5 MINUTES)) @@ -67,7 +67,7 @@ datum/game_mode/mutiny "classified security operations", "science-defying raw elemental chaos" ) - command_alert("The presence of [pick(reasons)] in the region is tying up all available local emergency resources; emergency response teams cannot be called at this time.","Emergency Transmission") + command_announcement.Announce("The presence of [pick(reasons)] in the region is tying up all available local emergency resources; emergency response teams cannot be called at this time.","Emergency Transmission") // Returns an array in case we want to expand on this later. proc/get_head_loyalist_candidates() diff --git a/code/game/gamemodes/nations/flagprocs.dm b/code/game/gamemodes/nations/flagprocs.dm index 439167273ac..b7dc23a2913 100644 --- a/code/game/gamemodes/nations/flagprocs.dm +++ b/code/game/gamemodes/nations/flagprocs.dm @@ -20,7 +20,7 @@ /obj/item/flag/nation/light() return -/obj/item/flag/nation/attackby(var/obj/item/weapon/W, var/mob/user) +/obj/item/flag/nation/attackby(var/obj/item/weapon/W, var/mob/user, params) return /obj/item/flag/nation/attack_paw() diff --git a/code/game/gamemodes/nations/nations.dm b/code/game/gamemodes/nations/nations.dm index ec180e07279..afaab542d73 100644 --- a/code/game/gamemodes/nations/nations.dm +++ b/code/game/gamemodes/nations/nations.dm @@ -28,7 +28,7 @@ datum/game_mode/nations return ..() /datum/game_mode/nations/send_intercept() - command_alert("Due to recent and COMPLETELY UNFOUNDED allegations of massive fraud and insider trading \ + command_announcement.Announce("Due to recent and COMPLETELY UNFOUNDED allegations of massive fraud and insider trading \ affecting trillions of investors, the Nanotrasen Corporation has decided to liquidate all \ assets of the Centcom Division in order to pay the massive legal fees that will be incurred \ during the following centuries long court process. Therefore, all current employment contracts \ diff --git a/code/game/gamemodes/newobjective.dm b/code/game/gamemodes/newobjective.dm index df6b31dec48..973e8f4e427 100644 --- a/code/game/gamemodes/newobjective.dm +++ b/code/game/gamemodes/newobjective.dm @@ -883,7 +883,7 @@ datum return 2 hyper_cell - steal_target = /obj/item/weapon/cell/hyper + steal_target = /obj/item/weapon/stock_parts/cell/hyper explanation_text = "Steal a hyper capacity power cell." weight = 20 @@ -1398,7 +1398,7 @@ datum var/turf/T = get_turf(target.current) if(target.current.stat == 2) return 1 - else if((T) && (T.z != 1))//If they leave the station they count as dead for this + else if((T) && !(T.z in config.station_levels))//If they leave the station they count as dead for this return 2 else return 0 diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index de7bc051054..4cd820a7af2 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -132,6 +132,7 @@ proc/issyndicate(mob/living/M as mob) synd_mind.current.loc = synd_spawn[spawnpos] forge_syndicate_objectives(synd_mind) + create_syndicate(synd_mind) greet_syndicate(synd_mind) equip_syndicate(synd_mind.current) @@ -162,7 +163,37 @@ proc/issyndicate(mob/living/M as mob) spawn (rand(waittime_l, waittime_h)) send_intercept() return ..() + +/datum/game_mode/proc/create_syndicate(var/datum/mind/synd_mind) // So we don't have inferior species as ops - randomize a human + var/mob/living/carbon/human/M = synd_mind.current + M.set_species("Human",1) + M.dna.ready_dna(M) // Quadriplegic Nuke Ops won't be participating in the paralympics + var/hair_c = pick("#8B4513","#000000","#FF4500","#FFD700") // Brown, black, red, blonde + var/eye_c = pick("#000000","#8B4513","1E90FF") // Black, brown, blue + var/skin_tone = pick(-50, -30, -10, 0, 0, 0, 10) // Caucasian/black + var/hair_style = "Bald" + var/facial_hair_style = "Shaved" + if(M.gender == MALE) + hair_style = pick(hair_styles_male_list) + facial_hair_style = pick(facial_hair_styles_list) + else + hair_style = pick(hair_styles_female_list) + if(prob(5)) + facial_hair_style = pick(facial_hair_styles_list) + + M.r_facial = hex2num(copytext(hair_c, 2, 4)) + M.g_facial = hex2num(copytext(hair_c, 4, 6)) + M.b_facial = hex2num(copytext(hair_c, 6, 8)) + M.r_hair = hex2num(copytext(hair_c, 2, 4)) + M.g_hair = hex2num(copytext(hair_c, 4, 6)) + M.b_hair = hex2num(copytext(hair_c, 6, 8)) + M.r_eyes = hex2num(copytext(eye_c, 2, 4)) + M.g_eyes = hex2num(copytext(eye_c, 4, 6)) + M.b_eyes = hex2num(copytext(eye_c, 6, 8)) + M.s_tone = skin_tone + M.h_style = hair_style + M.f_style = facial_hair_style /datum/game_mode/proc/prepare_syndicate_leader(var/datum/mind/synd_mind, var/nuke_code) var/leader_title = pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord") @@ -246,9 +277,6 @@ proc/issyndicate(mob/living/M as mob) U.hidden_uplink.uses = 20 synd_mob.equip_to_slot_or_del(U, slot_in_backpack) - var/obj/item/clothing/suit/space/rig/syndi/new_suit = new(synd_mob) - var/obj/item/clothing/head/helmet/space/rig/syndi/new_helmet = new(synd_mob) - if(synd_mob.species) /* @@ -261,28 +289,12 @@ proc/issyndicate(mob/living/M as mob) var/race = synd_mob.species.name switch(race) - if("Unathi") - new_suit.species_restricted = list("Unathi") - new_helmet.species_restricted = list("Unathi") - if("Tajaran") - new_suit.species_restricted = list("Tajaran") - new_helmet.species_restricted = list("Tajaran") - if("Skrell") - new_suit.species_restricted = list("Skrell") - new_helmet.species_restricted = list("Skrell") if("Vox" || "Vox Armalis") - synd_mob.equip_to_slot_or_del(new /obj/item/clothing/mask/breath(synd_mob), slot_wear_mask) + synd_mob.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/syndicate(synd_mob), slot_wear_mask) synd_mob.equip_to_slot_or_del(new /obj/item/weapon/tank/nitrogen(synd_mob), slot_l_hand) synd_mob.internal = synd_mob.l_hand if (synd_mob.internals) synd_mob.internals.icon_state = "internal1" - new_suit.species_restricted = list ("Vox", "Vox Armalis") - new_helmet.species_restricted = list ("Vox", "Vox Armalis") - - - synd_mob.equip_to_slot_or_del(new_suit, slot_wear_suit) - synd_mob.equip_to_slot_or_del(new_helmet, slot_head) - var/obj/item/weapon/implant/dexplosive/E = new/obj/item/weapon/implant/dexplosive(synd_mob) E.imp_in = synd_mob @@ -409,7 +421,7 @@ proc/issyndicate(mob/living/M as mob) /proc/nukelastname(var/mob/M as mob) //--All praise goes to NEO|Phyte, all blame goes to DH, and it was Cindi-Kate's idea. Also praise Urist for copypasta ho. var/randomname = pick(last_names) - var/newname = copytext(sanitize(input(M,"You are the nuke operative [pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord")]. Please choose a last name for your family.", "Name change",randomname)),1,MAX_NAME_LEN) + var/newname = sanitize(copytext(input(M,"You are the nuke operative [pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord")]. Please choose a last name for your family.", "Name change",randomname),1,MAX_NAME_LEN)) if (!newname) newname = randomname diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm index 8cfa326239b..c02d782612b 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/gamemodes/nuclear/nuclearbomb.dm @@ -23,11 +23,6 @@ var/bomb_set var/timing_wire var/removal_stage = 0 // 0 is no removal, 1 is covers removed, 2 is covers open, 3 is sealant open, 4 is unwrenched, 5 is removed from bolts. var/lastentered - var/data[0] - var/uiwidth - var/uiheight - var/uititle - flags = FPRINT use_power = 0 unacidable = 1 @@ -60,7 +55,7 @@ var/bomb_set nanomanager.update_uis(src) return -/obj/machinery/nuclearbomb/attackby(obj/item/weapon/O as obj, mob/user as mob) +/obj/machinery/nuclearbomb/attackby(obj/item/weapon/O as obj, mob/user as mob, params) if (istype(O, /obj/item/weapon/screwdriver)) src.add_fingerprint(user) if (src.auth) @@ -189,6 +184,10 @@ obj/machinery/nuclearbomb/proc/nukehack_win(mob/user as mob) ui_interact(user) /obj/machinery/nuclearbomb/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] + var/uiwidth + var/uiheight + var/uititle if(!src.opened) data["hacking"] = 0 data["auth"] = src.auth @@ -409,7 +408,7 @@ obj/machinery/nuclearbomb/proc/nukehack_win(mob/user as mob) var/off_station = 0 var/turf/bomb_location = get_turf(src) - if( bomb_location && (bomb_location.z == 1) ) + if( bomb_location && (bomb_location.z in config.station_levels) ) if( (bomb_location.x < (128-NUKERANGE)) || (bomb_location.x > (128+NUKERANGE)) || (bomb_location.y < (128-NUKERANGE)) || (bomb_location.y > (128+NUKERANGE)) ) off_station = 1 else diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm index a0b777d75dd..8d3a4fe1c17 100644 --- a/code/game/gamemodes/nuclear/pinpointer.dm +++ b/code/game/gamemodes/nuclear/pinpointer.dm @@ -2,7 +2,7 @@ name = "pinpointer" icon = 'icons/obj/device.dmi' icon_state = "pinoff" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT w_class = 2.0 item_state = "electronic" @@ -344,7 +344,7 @@ icon_state = "pinonfar" spawn(5) .() - + /obj/item/weapon/pinpointer/operative name = "operative pinpointer" icon = 'icons/obj/device.dmi' @@ -379,7 +379,7 @@ user << "Nearest operative: [nearest_op]." if(nearest_op == null && active) user << "No operatives detected within scanning range." - + /obj/item/weapon/pinpointer/operative/proc/point_at(atom/target, spawnself = 1) if(!active) return diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 964001722af..4c1e4ac1bd9 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -30,7 +30,7 @@ datum/objective proc/find_target() var/list/possible_targets = list() for(var/datum/mind/possible_target in ticker.minds) - if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != 2)) + if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != DEAD)) possible_targets += possible_target if(possible_targets.len > 0) target = pick(possible_targets) @@ -38,7 +38,7 @@ datum/objective proc/find_target_by_role(role, role_type=0)//Option sets either to check assigned role or special role. Default to assigned. var/list/possible_targets = list() for(var/datum/mind/possible_target in ticker.minds) - if((possible_target != owner) && ishuman(possible_target.current) && ((role_type ? possible_target.special_role : possible_target.assigned_role) == role) && (possible_target.current.stat != 2) ) + if((possible_target != owner) && ishuman(possible_target.current) && ((role_type ? possible_target.special_role : possible_target.assigned_role) == role) && (possible_target.current.stat != DEAD) ) possible_targets += possible_target if(possible_targets.len > 0) target = pick(possible_targets) @@ -47,7 +47,7 @@ datum/objective proc/find_target_with_special_role(role) var/list/possible_targets = list() for(var/datum/mind/possible_target in ticker.minds) - if((possible_target != owner) && ishuman(possible_target.current) && (role && possible_target.special_role == role || !role && possible_target.special_role) && (possible_target.current.stat != 2) ) + if((possible_target != owner) && ishuman(possible_target.current) && (role && possible_target.special_role == role || !role && possible_target.special_role) && (possible_target.current.stat != DEAD) ) possible_targets += possible_target if(possible_targets.len > 0) target = pick(possible_targets) @@ -104,7 +104,7 @@ datum/objective/mutiny if(target.current.stat == DEAD || !ishuman(target.current) || !target.current.ckey || !target.current.client) return 1 var/turf/T = get_turf(target.current) - if(T && (T.z != 1)) //If they leave the station they count as dead for this + if(T && !(T.z in config.station_levels)) //If they leave the station they count as dead for this return 2 return 0 return 1 @@ -139,7 +139,7 @@ datum/objective/mutiny/rp if(target in ticker.mode:head_revolutionaries) return 1 var/turf/T = get_turf(target.current) - if(T && (T.z != 1)) //If they leave the station they count as dead for this + if(T && !(T.z in config.station_levels)) //If they leave the station they count as dead for this rval = 2 return 0 return rval @@ -255,7 +255,7 @@ datum/objective/maroon if(target && target.current) if(target.current.stat == DEAD || issilicon(target.current) || isbrain(target.current) || target.current.z > 6 || !target.current.ckey) //Borgs/brains/AIs count as dead for traitor objectives. --NeoFite return 1 - if(target.current.z == 2) + if((target.current.z in config.admin_levels)) return 0 return 1 @@ -385,7 +385,7 @@ datum/objective/block for(var/mob/living/player in player_list) if(player.type in protected_mobs) continue if (player.mind) - if (player.stat != 2) + if (player.stat != DEAD) if (get_turf(player) in shuttle) return 0 return 1 @@ -420,7 +420,7 @@ datum/objective/escape return 0 if(!emergency_shuttle.returned()) return 0 - if(!owner.current || owner.current.stat ==2) + if(!owner.current || owner.current.stat == DEAD) return 0 var/turf/location = get_turf(owner.current.loc) if(!location) @@ -451,7 +451,14 @@ datum/objective/escape/escape_with_identity var/target_real_name // Has to be stored because the target's real_name can change over the course of the round find_target() - target = ..() + var/list/possible_targets = list() //Copypasta because NO_SCAN races, yay for snowflakes. + for(var/datum/mind/possible_target in ticker.minds) + if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != DEAD)) + var/mob/living/carbon/human/H = possible_target.current + if(!(H.species.flags & NO_SCAN)) + possible_targets += possible_target + if(possible_targets.len > 0) + target = pick(possible_targets) if(target && target.current) target_real_name = target.current.real_name explanation_text = "Escape on the shuttle or an escape pod with the identity of [target_real_name], the [target.assigned_role] while wearing their identification card." @@ -612,7 +619,7 @@ datum/objective/steal var/tmp_obj = new O.typepath var/custom_name = tmp_obj:name del(tmp_obj) - O.name = copytext(sanitize(input("Enter target name:", "Objective target", custom_name) as text|null),1,MAX_NAME_LEN) + O.name = sanitize(copytext(input("Enter target name:", "Objective target", custom_name) as text|null,1,MAX_NAME_LEN)) if (!O.name) return steal_target = O explanation_text = "Steal [O.name]." @@ -658,7 +665,7 @@ datum/objective/download check_completion() if(!ishuman(owner.current)) return 0 - if(!owner.current || owner.current.stat == 2) + if(!owner.current || owner.current.stat == DEAD) return 0 if(!(istype(owner.current:wear_suit, /obj/item/clothing/suit/space/space_ninja)&&owner.current:wear_suit:s_initialized)) return 0 @@ -685,25 +692,25 @@ datum/objective/capture var/captured_amount = 0 var/area/ninja/holding/A = locate() for(var/mob/living/carbon/human/M in A)//Humans. - if(M.stat==2)//Dead folks are worth less. + if(M.stat == DEAD)//Dead folks are worth less. captured_amount+=0.5 continue captured_amount+=1 for(var/mob/living/carbon/monkey/M in A)//Monkeys are almost worthless, you failure. captured_amount+=0.1 for(var/mob/living/carbon/alien/larva/M in A)//Larva are important for research. - if(M.stat==2) + if(M.stat == DEAD) captured_amount+=0.5 continue captured_amount+=1 for(var/mob/living/carbon/alien/humanoid/M in A)//Aliens are worth twice as much as humans. if(istype(M, /mob/living/carbon/alien/humanoid/queen))//Queens are worth three times as much as humans. - if(M.stat==2) + if(M.stat == DEAD) captured_amount+=1.5 else captured_amount+=3 continue - if(M.stat==2) + if(M.stat == DEAD) captured_amount+=1 continue captured_amount+=2 @@ -720,10 +727,14 @@ datum/objective/absorb var/n_p = 1 //autowin if (ticker.current_state == GAME_STATE_SETTING_UP) for(var/mob/new_player/P in player_list) - if(P.client && P.ready && P.mind!=owner) + if(P.client && P.ready && P.mind != owner) + if(P.client.prefs && (P.client.prefs.species == "Vox" || P.client.prefs.species == "Slime People" || P.client.prefs.species == "Machine")) // Special check for species that can't be absorbed. No better solution. + continue n_p ++ else if (ticker.current_state == GAME_STATE_PLAYING) for(var/mob/living/carbon/human/P in player_list) + if(P.species.flags & NO_SCAN) + continue if(P.client && !(P.mind in ticker.mode.changelings) && P.mind!=owner) n_p ++ target_amount = min(target_amount, n_p) @@ -738,12 +749,14 @@ datum/objective/absorb return 0 datum/objective/destroy + var/target_real_name find_target() var/list/possible_targets = active_ais(1) var/mob/living/silicon/ai/target_ai = pick(possible_targets) target = target_ai.mind if(target && target.current) - explanation_text = "Destroy [target.name], the experimental AI." + target_real_name = target.current.real_name + explanation_text = "Destroy [target_real_name], the AI." else explanation_text = "Free Objective" return target @@ -845,7 +858,7 @@ datum/objective/heist/kidnap var/list/priority_targets = list() for(var/datum/mind/possible_target in ticker.minds) - if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != 2) && (possible_target.assigned_role != "MODE")) + if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != DEAD) && (possible_target.assigned_role != "MODE")) possible_targets += possible_target for(var/role in roles) if(possible_target.assigned_role == role) @@ -865,7 +878,7 @@ datum/objective/heist/kidnap check_completion() if(target && target.current) - if (target.current.stat == 2) + if (target.current.stat == DEAD) return 0 // They're dead. Fail. //if (!target.current.restrained()) // return 0 // They're loose. Close but no cigar. diff --git a/code/game/gamemodes/revolution/anti_revolution.dm b/code/game/gamemodes/revolution/anti_revolution.dm index 171e4aad816..d656ccffc73 100644 --- a/code/game/gamemodes/revolution/anti_revolution.dm +++ b/code/game/gamemodes/revolution/anti_revolution.dm @@ -134,7 +134,7 @@ /datum/game_mode/anti_revolution/proc/check_crew_victory() for(var/datum/mind/head_mind in heads) var/turf/T = get_turf(head_mind.current) - if((head_mind) && (head_mind.current) && (head_mind.current.stat != 2) && T && (T.z == 1) && !head_mind.is_brigged(600)) + if((head_mind) && (head_mind.current) && (head_mind.current.stat != 2) && T && (T.z in config.station_levels) && !head_mind.is_brigged(600)) if(ishuman(head_mind.current)) return 0 return 1 diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index 620844a5135..cb04e55949a 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -10,6 +10,7 @@ /datum/game_mode var/list/datum/mind/head_revolutionaries = list() var/list/datum/mind/revolutionaries = list() + var/extra_heads = 0 /datum/game_mode/revolution name = "revolution" @@ -74,6 +75,9 @@ /datum/game_mode/revolution/post_setup() var/list/heads = get_living_heads() + if(num_players_started() >= 30) + heads += get_extra_living_heads() + extra_heads = 1 for(var/datum/mind/rev_mind in head_revolutionaries) for(var/datum/mind/head_mind in heads) @@ -106,9 +110,53 @@ checkwin_counter = 0 return 0 +/proc/get_rev_mode() + if(!ticker || !istype(ticker.mode, /datum/game_mode/revolution)) + return null + +/** + * LateSpawn hook. + * Called in newplayer.dm when a humanoid character joins the round after it started. + * Parameters: var/mob/living/carbon/human, var/rank + */ +/hook/latespawn/proc/add_latejoiner_heads(var/mob/living/carbon/human/H) + var/datum/game_mode/revolution/mode = get_rev_mode() + if (!mode) return 1 + + var/list/heads = list() + var/list/alt_positions = list("Warden", "Magistrate", "Blueshield", "Nanotrasen Representative") + + if(H.stat!=2 && H.mind && (H.mind.assigned_role in command_positions)) + heads += H + + if(mode.extra_heads) + if(H.stat!=2 && H.mind && (H.mind.assigned_role in alt_positions)) + heads += H + + for(var/datum/mind/rev_mind in mode.head_revolutionaries) + for(var/datum/mind/head_mind in heads) + var/datum/objective/mutiny/rev_obj = new + rev_obj.owner = rev_mind + rev_obj.target = head_mind + rev_obj.explanation_text = "Assassinate [head_mind.name], the [head_mind.assigned_role]." + rev_mind.objectives += rev_obj + rev_mind.current << "Additional Objective: Assassinate [head_mind.name], the [head_mind.assigned_role]." + + for(var/datum/mind/rev_mind in mode.revolutionaries) + for(var/datum/mind/head_mind in heads) + var/datum/objective/mutiny/rev_obj = new + rev_obj.owner = rev_mind + rev_obj.target = head_mind + rev_obj.explanation_text = "Assassinate [head_mind.name], the [head_mind.assigned_role]." + rev_mind.objectives += rev_obj + rev_mind.current << "Additional Objective: Assassinate [head_mind.name], the [head_mind.assigned_role]." + /datum/game_mode/proc/forge_revolutionary_objectives(var/datum/mind/rev_mind) var/list/heads = get_living_heads() + if(num_players_started() >= 30) + heads += get_extra_living_heads() + extra_heads = 1 for(var/datum/mind/head_mind in heads) var/datum/objective/mutiny/rev_obj = new rev_obj.owner = rev_mind @@ -135,7 +183,7 @@ if (mob.mind) if (mob.mind.assigned_role == "Clown") mob << "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself." - mob.mutations.Remove(M_CLUMSY) + mob.mutations.Remove(CLUMSY) var/obj/item/device/flash/T = new(mob) @@ -340,7 +388,7 @@ /datum/game_mode/revolution/proc/check_heads_victory() for(var/datum/mind/rev_mind in head_revolutionaries) var/turf/T = get_turf(rev_mind.current) - if((rev_mind) && (rev_mind.current) && (rev_mind.current.stat != 2) && rev_mind.current.client && T && (T.z == 1)) + if((rev_mind) && (rev_mind.current) && (rev_mind.current.stat != 2) && rev_mind.current.client && T && (T.z in config.station_levels)) if(ishuman(rev_mind.current)) return 0 return 1 @@ -369,7 +417,7 @@ if(headrev.current) if(headrev.current.stat == DEAD) text += "died" - else if(headrev.current.z != 1) + else if(!(headrev.current.z in config.station_levels)) text += "fled the station" else text += "survived the revolution" @@ -392,7 +440,7 @@ if(rev.current) if(rev.current.stat == DEAD) text += "died" - else if(rev.current.z != 1) + else if(!(rev.current.z in config.station_levels)) text += "fled the station" else text += "survived the revolution" @@ -409,6 +457,8 @@ var/text = "The heads of staff were:" var/list/heads = get_all_heads() + if(extra_heads) + heads += get_extra_heads() for(var/datum/mind/head in heads) var/target = (head in targets) if(target) @@ -417,7 +467,7 @@ if(head.current) if(head.current.stat == DEAD) text += "died" - else if(head.current.z != 1) + else if(!(head.current.z in config.station_levels)) text += "fled the station" else text += "survived the revolution" @@ -435,4 +485,4 @@ return istype(mind) && \ istype(mind.current, /mob/living/carbon/human) && \ !(mind.assigned_role in command_positions) && \ - !(mind.assigned_role in list("Security Officer", "Detective", "Warden")) + !(mind.assigned_role in list("Security Officer", "Detective", "Warden", "Nanotrasen Representative")) diff --git a/code/game/gamemodes/revolution/rp_revolution.dm b/code/game/gamemodes/revolution/rp_revolution.dm index 33977ca811e..110ff5769d1 100644 --- a/code/game/gamemodes/revolution/rp_revolution.dm +++ b/code/game/gamemodes/revolution/rp_revolution.dm @@ -124,7 +124,7 @@ // probably wanna export this stuff into a separate function for use by both // revs and heads //assume that only carbon mobs can become rev heads for now - if(!rev_mind.current:handcuffed && T && T.z == 1) + if(!rev_mind.current:handcuffed && T && (T.z in config.station_levels)) return 0 return 1 diff --git a/code/game/gamemodes/scoreboard.dm b/code/game/gamemodes/scoreboard.dm index 2617fe4e04e..acf8c879c3e 100644 --- a/code/game/gamemodes/scoreboard.dm +++ b/code/game/gamemodes/scoreboard.dm @@ -26,13 +26,13 @@ // Who is alive/dead, who escaped for (var/mob/living/silicon/ai/I in mob_list) - if (I.stat == 2 && I.z == 1) + if (I.stat == 2 && (I.z in config.station_levels)) score_deadaipenalty = 1 score_deadcrew += 1 for (var/mob/living/carbon/human/I in mob_list) // for (var/datum/ailment/disease/V in I.ailments) // if (!V.vaccine && !V.spread != "Remissive") score_disease++ - if (I.stat == 2 && I.z == 1) score_deadcrew += 1 + if (I.stat == 2 && (I.z in config.station_levels)) score_deadcrew += 1 if (I.job == "Clown") for(var/thing in I.attack_log) if(findtext(thing, "")) score_clownabuse++ @@ -102,7 +102,7 @@ if (location in bad_zone1) score_disc = 0 if (location in bad_zone2) score_disc = 0 if (location in bad_zone3) score_disc = 0 - if (A.loc.z != 1) score_disc = 0 + if (!(A.loc.z in config.station_levels)) score_disc = 0 */ if (score_nuked) for (var/obj/machinery/nuclearbomb/NUKE in machines) @@ -132,13 +132,13 @@ // Check station's power levels for (var/obj/machinery/power/apc/A in machines) - if (A.z != 1) continue - for (var/obj/item/weapon/cell/C in A.contents) + if (!(A.z in config.station_levels)) continue + for (var/obj/item/weapon/stock_parts/cell/C in A.contents) if (C.charge < 2300) score_powerloss += 1 // 200 charge leeway // Check how much uncleaned mess is on the station for (var/obj/effect/decal/cleanable/M in world) - if (M.z != 1) continue + if (!(M.z in config.station_levels)) continue if (istype(M, /obj/effect/decal/cleanable/blood/gibs/)) score_mess += 3 if (istype(M, /obj/effect/decal/cleanable/blood/)) score_mess += 1 // if (istype(M, /obj/effect/decal/cleanable/greenpuke)) score_mess += 1 diff --git a/code/game/gamemodes/setupgame.dm b/code/game/gamemodes/setupgame.dm index 96b1a3d7920..9936afa1d9a 100644 --- a/code/game/gamemodes/setupgame.dm +++ b/code/game/gamemodes/setupgame.dm @@ -76,6 +76,7 @@ TOXICFARTBLOCK = getAssignedBlock("TOXICFART", numsToAssign, good=1) STRONGBLOCK = getAssignedBlock("STRONG", numsToAssign, good=1) HORNSBLOCK = getAssignedBlock("HORNS", numsToAssign) + COMICBLOCK = getAssignedBlock("COMIC", numsToAssign) // Powers SOBERBLOCK = getAssignedBlock("SOBER", numsToAssign, good=1) @@ -97,7 +98,7 @@ // Disabilities LOUDBLOCK = getAssignedBlock("LOUD", numsToAssign) - WHISPERBLOCK = getAssignedBlock("WHISPER", numsToAssign) + //WHISPERBLOCK = getAssignedBlock("WHISPER", numsToAssign) BROKEN WITH NEW SAYCODE DIZZYBLOCK = getAssignedBlock("DIZZY", numsToAssign) @@ -134,22 +135,6 @@ //testing("DNA2: [numsToAssign.len] blocks are unused: [english_list(numsToAssign)]") -// Run AFTER genetics setup and AFTER species setup. -/proc/setup_species() - // SPECIES GENETICS FUN - for(var/name in all_species) - // I hate BYOND. Can't just call while it's in the list. - var/datum/species/species = all_species[name] - if(species.default_block_names.len>0) - testing("Setting up genetics for [species.name] (needs [english_list(species.default_block_names)])") - species.default_blocks.Cut() - for(var/block=1;block[I] strikes a blow against \the [src], banishing it!
") spawn(1) @@ -197,7 +195,6 @@ throwforce = 15 damtype = BURN force = 15 - flags = FPRINT | TABLEPASS hitsound = 'sound/items/welder2.ogg' /obj/item/weapon/scrying/attack_self(mob/user as mob) diff --git a/code/game/gamemodes/wizard/raginmages.dm b/code/game/gamemodes/wizard/raginmages.dm index 0f41b86a11e..f726b1c2a22 100644 --- a/code/game/gamemodes/wizard/raginmages.dm +++ b/code/game/gamemodes/wizard/raginmages.dm @@ -73,7 +73,7 @@ var/mob/dead/observer/theghost = null spawn(rand(200, 600)) message_admins("SWF is still pissed, sending another wizard - [max_mages - mages_made] left.") - candidates = get_candidates(BE_WIZARD,,"wizard","Syndicate") + candidates = get_candidates(BE_WIZARD) if(!candidates.len) message_admins("No applicable ghosts for the next ragin' mage, asking ghosts instead.") var/time_passed = world.time diff --git a/code/game/gamemodes/wizard/rightandwrong.dm b/code/game/gamemodes/wizard/rightandwrong.dm index 3562603df8d..6d27d3fd636 100644 --- a/code/game/gamemodes/wizard/rightandwrong.dm +++ b/code/game/gamemodes/wizard/rightandwrong.dm @@ -1,7 +1,7 @@ /mob/proc/rightandwrong(var/summon_type) //0 = Summon Guns, 1 = Summon Magic - var/list/gunslist = list("taser","egun","laser","revolver","detective","c20r","nuclear","deagle","gyrojet","pulse","silenced","cannon","doublebarrel","shotgun","combatshotgun","bulldog","mateba","sabr","crossbow","saw","car") + var/list/gunslist = list("taser","egun","laser","revolver","detective","c20r","nuclear","deagle","gyrojet","pulse","silenced","cannon","doublebarrel","shotgun","combatshotgun","bulldog","mateba","sabr","crossbow","saw","car","boltaction") var/list/magiclist = list("fireball","smoke","blind","mindswap","forcewall","knock","horsemask","charge", "summonitem", "wandnothing", "wanddeath", "wandresurrection", "wandpolymorph", "wandteleport", "wanddoor", "wandfireball", "staffhealing", "armor", "scrying", "staffdoor", "special") var/list/magicspeciallist = list("staffchange","staffanimation", "wandbelt", "contract", "staffchaos") usr << "You summoned [summon_type ? "magic" : "guns"]!" @@ -70,6 +70,8 @@ new /obj/item/weapon/gun/projectile/automatic/l6_saw(get_turf(H)) if("car") new /obj/item/weapon/gun/projectile/automatic/c90gl(get_turf(H)) + if("boltaction") + new /obj/item/weapon/gun/projectile/shotgun/boltaction(get_turf(H)) else switch (randomizemagic) if("fireball") @@ -111,8 +113,8 @@ new /obj/item/clothing/head/helmet/space/rig/wizard(get_turf(H)) if("scrying") new /obj/item/weapon/scrying(get_turf(H)) - if (!(M_XRAY in H.mutations)) - H.mutations.Add(M_XRAY) + if (!(XRAY in H.mutations)) + H.mutations.Add(XRAY) H.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS) H.see_in_dark = 8 H.see_invisible = SEE_INVISIBLE_LEVEL_TWO diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index ef596e5d5ad..58b0077d31b 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -5,7 +5,6 @@ item_state = "electronic" desc = "A fragment of the legendary treasure known simply as the 'Soul Stone'. The shard still flickers with a fraction of the full artefacts power." w_class = 1.0 - flags = FPRINT | TABLEPASS slot_flags = SLOT_BELT origin_tech = "bluespace=4;materials=4" var/imprinted = "empty" @@ -90,9 +89,8 @@ icon = 'icons/obj/wizard.dmi' icon_state = "construct" desc = "A wicked machine used by those skilled in magical arts. It is inactive" - flags = FPRINT | TABLEPASS -/obj/structure/constructshell/attackby(obj/item/O as obj, mob/user as mob) +/obj/structure/constructshell/attackby(obj/item/O as obj, mob/user as mob, params) if(istype(O, /obj/item/device/soulstone)) O.transfer_soul("CONSTRUCT",src,user) @@ -118,7 +116,7 @@ U << "\red Capture failed!: \black The soul stone is full! Use or free an existing soul to make room." else for(var/obj/item/W in T) - T.drop_from_inventory(W) + T.unEquip(W) new /obj/effect/decal/remains/human(T.loc) //Spawns a skeleton T.invisibility = 101 var/atom/movable/overlay/animation = new /atom/movable/overlay( T.loc ) diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index d546970870d..43f58169edf 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -6,14 +6,13 @@ throw_speed = 1 throw_range = 5 w_class = 1.0 - flags = FPRINT | TABLEPASS var/uses = 5 var/temp = null var/max_uses = 5 var/op = 1 var/activepage -/obj/item/weapon/spellbook/attackby(obj/item/O as obj, mob/user as mob) +/obj/item/weapon/spellbook/attackby(obj/item/O as obj, mob/user as mob, params) if(istype(O, /obj/item/weapon/contract)) var/obj/item/weapon/contract/contract = O if(contract.used) @@ -367,8 +366,8 @@ if("scrying") feedback_add_details("wizard_spell_learned","SO") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells new /obj/item/weapon/scrying(get_turf(H)) - if (!(M_XRAY in H.mutations)) - H.mutations.Add(M_XRAY) + if (!(XRAY in H.mutations)) + H.mutations.Add(XRAY) H.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS) H.see_in_dark = 8 H.see_invisible = SEE_INVISIBLE_LEVEL_TWO @@ -555,12 +554,13 @@ if(istype(user, /mob/living/carbon/human)) user <<"HOR-SIE HAS RISEN" var/obj/item/clothing/mask/horsehead/magichead = new /obj/item/clothing/mask/horsehead - magichead.canremove = 0 //curses! + magichead.flags |= NODROP //curses! magichead.flags_inv = null //so you can still see their face magichead.voicechange = 1 //NEEEEIIGHH - user.drop_from_inventory(user.wear_mask) + if(!user.unEquip(user.wear_mask)) + del user.wear_mask user.equip_to_slot_if_possible(magichead, slot_wear_mask, 1, 1) - del(src) + del src else user <<"I say thee neigh" diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index cd59d23d0b5..78be858d796 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -116,7 +116,7 @@ var/wizard_name_second = pick(wizard_second) var/randomname = "[wizard_name_first] [wizard_name_second]" spawn(0) - var/newname = copytext(sanitize(input(wizard_mob, "You are the Space Wizard. Would you like to change your name to something else?", "Name change", randomname) as null|text),1,MAX_NAME_LEN) + var/newname = sanitize(copytext(input(wizard_mob, "You are the Space Wizard. Would you like to change your name to something else?", "Name change", randomname) as null|text,1,MAX_NAME_LEN)) if (!newname) newname = randomname diff --git a/code/game/gamemodes/xenos/xenos.dm b/code/game/gamemodes/xenos/xenos.dm index 0d4c7f06b1b..b8f57122a7c 100644 --- a/code/game/gamemodes/xenos/xenos.dm +++ b/code/game/gamemodes/xenos/xenos.dm @@ -18,8 +18,6 @@ var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds) var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds) - var/xenoai = 0 //Should the Xenos have their own AI? - var/xenoborg = 0 //Should the Xenos have their own borg? var/gammaratio = 4 //At what alien to human ratio will the Gamma security level be called and the nuke be made available? /datum/game_mode/xenos/announce() @@ -70,48 +68,12 @@ del(A) continue - var/xenoai_selected = 0 - var/xenoborg_selected = 0 var/xenoqueen_selected = 0 var/spawnpos = 1 for(var/datum/mind/xeno_mind in xenos) if(spawnpos > xenos_spawn.len) spawnpos = 1 - //XenoAI selection - if(xenoai && !xenoai_selected) - var/mob/living/silicon/ai/O = new(xenos_spawn[spawnpos],,,1)//No MMI but safety is in effect. - O.invisibility = 0 - O.aiRestorePowerRoutine = 0 - - if(xeno_mind.current) - xeno_mind.transfer_to(O) - O.mind.original = O - else - O.key = xeno_mind.current.key - - //del(xeno_mind) - var/obj/loc_landmark - for(var/obj/effect/landmark/start/sloc in landmarks_list) - if (sloc.name == "XenoAI") - loc_landmark = sloc - O.loc = loc_landmark.loc - O.icon_state = "ai-alien" - O.verbs.Remove(,/mob/living/silicon/ai/proc/ai_call_shuttle,/mob/living/silicon/ai/proc/ai_camera_track, \ - /mob/living/silicon/ai/proc/ai_camera_list, /mob/living/silicon/ai/proc/ai_network_change, \ - /mob/living/silicon/ai/proc/ai_statuschange, /mob/living/silicon/ai/proc/ai_hologram_change, \ - /mob/living/silicon/ai/proc/toggle_camera_light,/mob/living/silicon/ai/verb/pick_icon) - O.laws = new /datum/ai_laws/alienmov - O.name = "Alien AI" - O.real_name = name - xeno_mind.name = O.name - O.alienAI = 1 - O.network = list("SS13","Xeno") - O.holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo3")) - O.alien_talk_understand = 1 - xenoai_selected = 1 - spawnpos++ - continue //XenoQueen Selection if(!xenoqueen_selected) var/mob/living/carbon/alien/humanoid/queen/O = new(xenos_spawn[spawnpos]) @@ -124,37 +86,6 @@ xenoqueen_selected = 1 spawnpos++ continue - //XenoBorg Selection - if(xenoborg && !xenoborg_selected) - var/mob/living/silicon/robot/O = new(xenos_spawn[spawnpos],0,0,1) - O.mmi = new /obj/item/device/mmi(O) - O.mmi.alien = 1 - O.mmi.transfer_identity(xeno_mind.current)//Does not transfer key/client. - O.cell = new(O) - O.cell.maxcharge = 25000 - O.cell.charge = 25000 - O.gender = xeno_mind.current.gender - O.invisibility = 0 - O.key = xeno_mind.current.key - //del(xeno_mind) - O.job = "Alien Cyborg" - O.name = "Alien Cyborg" - O.real_name = name - xeno_mind.name = O.name - O.module = new /obj/item/weapon/robot_module/alien/hunter(src) - O.hands.icon_state = "standard" - O.icon = 'icons/mob/alien.dmi' - O.icon_state = "xenoborg-state-a" - O.modtype = "Xeno-Hu" - O.connected_ai = select_active_alien_ai() - O.laws = new /datum/ai_laws/alienmov() - O.scrambledcodes = 1 - O.hiddenborg = 1 - O.alien_talk_understand = 1 - feedback_inc("xeborg_hunter",1) - xenoborg_selected = 1 - spawnpos++ - continue //Additional larvas if playercount > 20 else var/mob/living/carbon/alien/larva/O = new(xenos_spawn[spawnpos]) @@ -200,10 +131,10 @@ else if(playeralienratio >= gammaratio && !gammacalled) gammacalled = 1 - command_alert("The aliens have nearly succeeded in capturing the station and exterminating the crew. Activate the nuclear failsafe to stop the alien threat once and for all. The Nuclear Authentication Code is [get_nuke_code()] ", "Alien Lifeform Alert") + command_announcement.Announce("The aliens have nearly succeeded in capturing the station and exterminating the crew. Activate the nuclear failsafe to stop the alien threat once and for all. The Nuclear Authentication Code is [get_nuke_code()] ", "Alien Lifeform Alert") set_security_level("gamma") var/obj/machinery/door/airlock/vault/V = locate(/obj/machinery/door/airlock/vault) in world - if(V && V.z == 1) + if(V && (V.z in config.station_levels)) V.locked = 0 V.update_icon() return ..() @@ -230,7 +161,7 @@ var/list/livingxenos = list() for(var/datum/mind/xeno in xenos) if((xeno) && (xeno.current) && (xeno.current.stat != 2) && (xeno.current.client)) - if(istype(xeno.current,/mob/living/carbon/alien) || (xenoborg && isrobot(xeno.current)) || (xenoai && isAI(xeno.current))) + if(istype(xeno.current,/mob/living/carbon/alien)) livingxenos += xeno return livingxenos.len @@ -238,7 +169,7 @@ var/list/livingplayers = list() for(var/mob/M in player_list) var/turf/T = get_turf(M) - if((M) && (M.stat != 2) && M.client && T && (T.z == 1 || emergency_shuttle.departed && (T.z == 1 || T.z == 2))) + if((M) && (M.stat != 2) && M.client && T && ((T.z in config.station_levels) || emergency_shuttle.departed && ((T.z in config.station_levels) || (T.z in config.admin_levels)))) if(ishuman(M)) livingplayers += 1 return livingplayers.len diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index f9219462ad2..f318b5311ae 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -508,6 +508,15 @@ return assignment return "Unknown" + +proc/GetIdCard(var/mob/living/carbon/human/H) + if(H.wear_id) + var/id = H.wear_id.GetID() + if(id) + return id + if(H.get_active_hand()) + var/obj/item/I = H.get_active_hand() + return I.GetID() proc/FindNameFromID(var/mob/living/carbon/human/H) ASSERT(istype(H)) diff --git a/code/game/jobs/job/science.dm b/code/game/jobs/job/science.dm index 177bc7ecfc2..4ec89fad037 100644 --- a/code/game/jobs/job/science.dm +++ b/code/game/jobs/job/science.dm @@ -140,7 +140,7 @@ H.equip_or_collect(new /obj/item/device/pda/roboticist(H), slot_wear_pda) H.equip_or_collect(new /obj/item/clothing/suit/storage/labcoat(H), slot_wear_suit) // H.equip_or_collect(new /obj/item/clothing/gloves/black(H), slot_gloves) - H.equip_or_collect(new /obj/item/weapon/storage/toolbox/mechanical(H), slot_l_hand) + H.equip_or_collect(new /obj/item/weapon/storage/belt/utility/full(H), slot_belt) if(H.backbag == 1) H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) else diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index 2ad488ab6c4..45d19411b32 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -35,10 +35,10 @@ H.equip_or_collect(new /obj/item/weapon/gun/energy/gun(H), slot_s_store) if(H.backbag == 1) H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_l_store) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_l_store) else H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_in_backpack) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_in_backpack) H.equip_or_collect(new /obj/item/weapon/melee/telebaton(H.back), slot_in_backpack) var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H @@ -81,10 +81,10 @@ H.equip_or_collect(new /obj/item/weapon/gun/energy/advtaser(H), slot_s_store) if(H.backbag == 1) H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_l_hand) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_l_hand) else H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_in_backpack) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_in_backpack) var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 @@ -147,7 +147,7 @@ L.part = affected H.dna.SetSEState(SOBERBLOCK,1) - H.mutations += M_SOBER + H.mutations += SOBER H.check_mutations = 1 return 1 @@ -180,10 +180,10 @@ H.equip_or_collect(new /obj/item/device/flash(H), slot_l_store) if(H.backbag == 1) H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_l_hand) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_l_hand) else H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_in_backpack) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_in_backpack) var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 @@ -255,10 +255,10 @@ H.equip_or_collect(new /obj/item/device/flash(H), slot_l_store) if(H.backbag == 1) H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_l_hand) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_l_hand) else H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) - H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_in_backpack) + H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_in_backpack) var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 diff --git a/code/game/jobs/job/supervisor.dm b/code/game/jobs/job/supervisor.dm index d0dd51fb59f..94f555b2b30 100644 --- a/code/game/jobs/job/supervisor.dm +++ b/code/game/jobs/job/supervisor.dm @@ -1,3 +1,4 @@ +var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) /datum/job/captain title = "Captain" flag = CAPTAIN @@ -20,7 +21,7 @@ if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) var/obj/item/clothing/under/U = new /obj/item/clothing/under/rank/captain(H) - U.hastie = new /obj/item/clothing/tie/medal/gold/captain(U) + U.accessories += new /obj/item/clothing/accessory/medal/gold/captain(U) H.equip_or_collect(U, slot_w_uniform) H.equip_or_collect(new /obj/item/device/pda/captain(H), slot_wear_pda) H.equip_or_collect(new /obj/item/clothing/suit/armor/vest/capcarapace(H), slot_wear_suit) @@ -35,7 +36,7 @@ var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 - world << "Captain [H.real_name] on deck!" + captain_announcement.Announce("All hands, captain [H.real_name] on deck!") var/datum/organ/external/affected = H.organs_by_name["head"] affected.implants += L L.part = affected @@ -162,7 +163,7 @@ equip(var/mob/living/carbon/human/H) if(!H) return 0 - H.equip_or_collect(new /obj/item/device/radio/headset/heads/blueshield(H), slot_l_ear) + H.equip_or_collect(new /obj/item/device/radio/headset/heads/blueshield/alt(H), slot_l_ear) switch(H.backbag) if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack/security(H), slot_back) if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back) diff --git a/code/game/jobs/job/support.dm b/code/game/jobs/job/support.dm index 7c022c8466d..96e5d089b22 100644 --- a/code/game/jobs/job/support.dm +++ b/code/game/jobs/job/support.dm @@ -31,7 +31,7 @@ H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack) H.dna.SetSEState(SOBERBLOCK,1) - H.mutations += M_SOBER + H.mutations += SOBER H.check_mutations = 1 return 1 @@ -226,7 +226,9 @@ H.equip_or_collect(new /obj/item/toy/crayon/rainbow(H), slot_in_backpack) H.equip_or_collect(new /obj/item/weapon/storage/fancy/crayons(H), slot_in_backpack) H.equip_or_collect(new /obj/item/weapon/reagent_containers/spray/waterflower(H), slot_in_backpack) - H.mutations.Add(M_CLUMSY) + H.mutations.Add(CLUMSY) + H.dna.SetSEState(COMICBLOCK,1,1) + genemutcheck(H,COMICBLOCK,null,MUTCHK_FORCED) return 1 @@ -245,8 +247,7 @@ equip(var/mob/living/carbon/human/H) if(!H) return 0 - if(H.backbag == 2) H.equip_or_collect(new /obj/item/weapon/storage/backpack(H), slot_back) - if(H.backbag == 3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back) + H.equip_or_collect(new /obj/item/weapon/storage/backpack/mime(H), slot_back) if(H.gender == FEMALE) H.equip_or_collect(new /obj/item/clothing/under/sexymime(H), slot_w_uniform) H.equip_or_collect(new /obj/item/clothing/mask/gas/sexymime(H), slot_wear_mask) @@ -259,14 +260,9 @@ H.equip_or_collect(new /obj/item/clothing/gloves/color/white(H), slot_gloves) H.equip_or_collect(new /obj/item/clothing/head/beret(H), slot_head) H.equip_or_collect(new /obj/item/clothing/suit/suspenders(H), slot_wear_suit) - if(H.backbag == 1) - H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) - H.equip_or_collect(new /obj/item/toy/crayon/mime(H), slot_l_store) - H.equip_or_collect(new /obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing(H), slot_l_hand) - else - H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) - H.equip_or_collect(new /obj/item/toy/crayon/mime(H), slot_in_backpack) - H.equip_or_collect(new /obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing(H), slot_in_backpack) + H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) + H.equip_or_collect(new /obj/item/toy/crayon/mime(H), slot_in_backpack) + H.equip_or_collect(new /obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing(H), slot_in_backpack) H.verbs += /client/proc/mimespeak H.verbs += /client/proc/mimewall H.mind.special_verbs += /client/proc/mimespeak diff --git a/code/game/jobs/job/support_chaplain.dm b/code/game/jobs/job/support_chaplain.dm index f02f111c0fb..d56f478fc42 100644 --- a/code/game/jobs/job/support_chaplain.dm +++ b/code/game/jobs/job/support_chaplain.dm @@ -24,7 +24,7 @@ H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) spawn(0) var/religion_name = "Christianity" - var/new_religion = copytext(sanitize(input(H, "You are the crew services officer. Would you like to change your religion? Default is Christianity, in SPACE.", "Name change", religion_name)),1,MAX_NAME_LEN) + var/new_religion = sanitize(copytext(input(H, "You are the crew services officer. Would you like to change your religion? Default is Christianity, in SPACE.", "Name change", religion_name),1,MAX_NAME_LEN)) if (!new_religion) new_religion = religion_name @@ -59,7 +59,7 @@ spawn(1) var/deity_name = "Space Jesus" - var/new_deity = copytext(sanitize(input(H, "Would you like to change your deity? Default is Space Jesus.", "Name change", deity_name)),1,MAX_NAME_LEN) + var/new_deity = sanitize(copytext(input(H, "Would you like to change your deity? Default is Space Jesus.", "Name change", deity_name),1,MAX_NAME_LEN)) if ((length(new_deity) == 0) || (new_deity == "Space Jesus") ) new_deity = deity_name diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index 1e7dfe99d5f..f678b3afc1b 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -526,6 +526,7 @@ var/global/datum/controller/occupations/job_master var/obj/item/device/pda/pda = locate(/obj/item/device/pda,H) pda.owner = H.real_name pda.ownjob = C.assignment + pda.ownrank = C.rank pda.name = "PDA-[H.real_name] ([pda.ownjob])" return 1 diff --git a/code/game/machinery/Freezer.dm b/code/game/machinery/Freezer.dm index a1fb735efd3..070b99571ce 100644 --- a/code/game/machinery/Freezer.dm +++ b/code/game/machinery/Freezer.dm @@ -22,6 +22,18 @@ component_parts += new /obj/item/stack/cable_coil(src, 1) RefreshParts() +/obj/machinery/atmospherics/unary/cold_sink/freezer/upgraded/New() + ..() + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/thermomachine(src) + component_parts += new /obj/item/weapon/stock_parts/matter_bin/super(src) + component_parts += new /obj/item/weapon/stock_parts/matter_bin/super(src) + component_parts += new /obj/item/weapon/stock_parts/micro_laser/ultra(src) + component_parts += new /obj/item/weapon/stock_parts/micro_laser/ultra(src) + component_parts += new /obj/item/weapon/stock_parts/console_screen(src) + component_parts += new /obj/item/stack/cable_coil(src, 1) + RefreshParts() + /obj/machinery/atmospherics/unary/cold_sink/freezer/RefreshParts() var/H var/T @@ -32,7 +44,7 @@ min_temperature = T0C - (170 + (T*15)) current_heat_capacity = 1000 * ((H - 1) ** 2) -/obj/machinery/atmospherics/unary/cold_sink/freezer/attackby(obj/item/I, mob/user) +/obj/machinery/atmospherics/unary/cold_sink/freezer/attackby(obj/item/I, mob/user, params) if(default_deconstruction_screwdriver(user, "freezer-o", "freezer", I)) on = 0 update_icon() @@ -85,9 +97,13 @@ data["on"] = on ? 1 : 0 data["gasPressure"] = round(air_contents.return_pressure()) data["gasTemperature"] = round(air_contents.temperature) + data["gasTemperatureCelsius"] = round(air_contents.temperature - T0C,1) + if(air_contents.total_moles == 0 && air_contents.temperature == 0) + data["gasTemperatureCelsius"] = 0 data["minGasTemperature"] = round(min_temperature) data["maxGasTemperature"] = round(T20C) data["targetGasTemperature"] = round(current_temperature) + data["targetGasTemperatureCelsius"] = round(current_temperature - T0C,1) var/temp_class = "good" if (air_contents.temperature > (T0C - 20)) @@ -101,7 +117,7 @@ if (!ui) // the ui does not exist, so we'll create a new() one // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "freezer.tmpl", "Gas Cooling System", 440, 300) + ui = new(user, src, ui_key, "freezer.tmpl", "Gas Cooling System", 520, 300) // when the ui is first opened this is the data it will use ui.set_initial_data(data) // open the new ui window @@ -110,6 +126,8 @@ ui.set_auto_update(1) /obj/machinery/atmospherics/unary/cold_sink/freezer/Topic(href, href_list) + if(..()) + return 1 if (href_list["toggleStatus"]) src.on = !src.on update_icon() @@ -157,6 +175,21 @@ component_parts += new /obj/item/weapon/stock_parts/console_screen(src) component_parts += new /obj/item/stack/cable_coil(src, 1) RefreshParts() + +/obj/machinery/atmospherics/unary/heat_reservoir/heater/upgraded/New() + ..() + var/obj/item/weapon/circuitboard/thermomachine/H = new /obj/item/weapon/circuitboard/thermomachine(null) + H.build_path = /obj/machinery/atmospherics/unary/heat_reservoir/heater + H.name = "circuit board (Heater)" + component_parts = list() + component_parts += H + component_parts += new /obj/item/weapon/stock_parts/matter_bin/super(src) + component_parts += new /obj/item/weapon/stock_parts/matter_bin/super(src) + component_parts += new /obj/item/weapon/stock_parts/micro_laser/ultra(src) + component_parts += new /obj/item/weapon/stock_parts/micro_laser/ultra(src) + component_parts += new /obj/item/weapon/stock_parts/console_screen(src) + component_parts += new /obj/item/stack/cable_coil(src, 1) + RefreshParts() /obj/machinery/atmospherics/unary/heat_reservoir/heater/RefreshParts() var/H @@ -168,7 +201,7 @@ max_temperature = T20C + (140 * T) current_heat_capacity = 1000 * ((H - 1) ** 2) -/obj/machinery/atmospherics/unary/heat_reservoir/heater/attackby(obj/item/I, mob/user) +/obj/machinery/atmospherics/unary/heat_reservoir/heater/attackby(obj/item/I, mob/user, params) if(default_deconstruction_screwdriver(user, "heater-o", "heater", I)) on = 0 update_icon() @@ -221,9 +254,13 @@ data["on"] = on ? 1 : 0 data["gasPressure"] = round(air_contents.return_pressure()) data["gasTemperature"] = round(air_contents.temperature) + data["gasTemperatureCelsius"] = round(air_contents.temperature - T0C,1) + if(air_contents.total_moles == 0 && air_contents.temperature == 0) + data["gasTemperatureCelsius"] = 0 data["minGasTemperature"] = round(T20C) data["maxGasTemperature"] = round(T20C+max_temperature) data["targetGasTemperature"] = round(current_temperature) + data["targetGasTemperatureCelsius"] = round(current_temperature - T0C,1) var/temp_class = "normal" if (air_contents.temperature > (T20C+40)) @@ -235,7 +272,7 @@ if (!ui) // the ui does not exist, so we'll create a new() one // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "freezer.tmpl", "Gas Heating System", 440, 300) + ui = new(user, src, ui_key, "freezer.tmpl", "Gas Heating System", 520, 300) // when the ui is first opened this is the data it will use ui.set_initial_data(data) // open the new ui window diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm index 837759072ed..9cdbe1fd662 100644 --- a/code/game/machinery/OpTable.dm +++ b/code/game/machinery/OpTable.dm @@ -43,7 +43,7 @@ del(src) /obj/machinery/optable/attack_paw(mob/user as mob) - if ((M_HULK in usr.mutations)) + if ((HULK in usr.mutations)) usr << text("\blue You destroy the operating table.") visible_message("\red [usr] destroys the operating table!") src.density = 0 @@ -56,7 +56,7 @@ return /obj/machinery/optable/attack_hand(mob/user as mob) - if (M_HULK in usr.mutations) + if (HULK in usr.mutations) usr << text("\blue You destroy the table.") visible_message("\red [usr] destroys the operating table!") src.density = 0 @@ -73,7 +73,13 @@ /obj/machinery/optable/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob) - if(usr.stat || !ishuman(usr) || usr.restrained() || !check_table(usr) || usr.weakened || usr.stunned) + if(usr.stat || (!ishuman(user) && !isrobot(user)) || user.restrained() || !check_table(user) || user.weakened || user.stunned) + return + + if(!ismob(O)) //humans only + return + + if(istype(O, /mob/living/simple_animal) || istype(O, /mob/living/silicon)) //animals and robots dont fit return var/mob/living/L = O @@ -124,7 +130,7 @@ take_victim(usr,usr) -/obj/machinery/optable/attackby(obj/item/weapon/W as obj, mob/living/carbon/user as mob) +/obj/machinery/optable/attackby(obj/item/weapon/W as obj, mob/living/carbon/user as mob, params) if (istype(W, /obj/item/weapon/grab)) if(iscarbon(W:affecting)) take_victim(W:affecting,usr) diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm index a7124c21120..cdf5e479ef5 100644 --- a/code/game/machinery/PDApainter.dm +++ b/code/game/machinery/PDApainter.dm @@ -40,7 +40,7 @@ src.colorlist += D -/obj/machinery/pdapainter/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/machinery/pdapainter/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(istype(O, /obj/item/device/pda)) if(storedpda) user << "There is already a PDA inside." diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 8785634bc55..841916a9a74 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -13,6 +13,7 @@ dir = 8 idle_power_usage = 250 active_power_usage = 500 + interact_offline = 1 /obj/machinery/sleep_console/power_change() if(stat & BROKEN) @@ -67,8 +68,15 @@ src.connected = sleepernew return return + +/obj/machinery/sleeper/attack_animal(var/mob/living/simple_animal/M)//Stop putting hostile mobs in things guise + if(M.environment_smash) + M.do_attack_animation(src) + visible_message("[M.name] smashes [src] apart!") + qdel(src) + return -/obj/machinery/sleep_console/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob) +/obj/machinery/sleep_console/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob, params) if (istype(G, /obj/item/weapon/screwdriver)) default_deconstruction_screwdriver(user, "console-p", "console", G) return @@ -284,7 +292,7 @@ return -/obj/machinery/sleeper/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob) +/obj/machinery/sleeper/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob, params) if(istype(G, /obj/item/weapon/reagent_containers/glass)) if(!beaker) beaker = G @@ -506,7 +514,7 @@ return if(user.restrained() || user.stat || user.weakened || user.stunned || user.paralysis || user.resting) //are you cuffed, dying, lying, stunned or other return - if(O.anchored || get_dist(user, src) > 1 || get_dist(user, O) > 1 || user.contents.Find(src)) // is the mob anchored, too far away from you, or are you too far away from the source + if(get_dist(user, src) > 1 || get_dist(user, O) > 1 || user.contents.Find(src)) // is the mob anchored, too far away from you, or are you too far away from the source return if(!ismob(O)) //humans only return diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 98747fbb3a6..c4994ebe746 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -320,7 +320,7 @@ */ -/obj/machinery/body_scanconsole/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob) +/obj/machinery/body_scanconsole/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob, params) if (istype(G, /obj/item/weapon/screwdriver)) default_deconstruction_screwdriver(user, "bodyscannerconsole-p", "bodyscannerconsole", G) return @@ -519,8 +519,8 @@ return /obj/machinery/body_scanconsole/Topic(href, href_list) - if(stat & (BROKEN|NOPOWER)) return - if(usr.stat || usr.restrained()) return + if(..()) + return 1 if (href_list["print_p"]) if (!(src.printing) && src.printing_text) diff --git a/code/game/machinery/ai_slipper.dm b/code/game/machinery/ai_slipper.dm index 4df9f2a5a88..17ee041e81b 100644 --- a/code/game/machinery/ai_slipper.dm +++ b/code/game/machinery/ai_slipper.dm @@ -28,7 +28,7 @@ src.uses = uses src.power_change() -/obj/machinery/ai_slipper/attackby(obj/item/weapon/W, mob/user) +/obj/machinery/ai_slipper/attackby(obj/item/weapon/W, mob/user, params) if(stat & (NOPOWER|BROKEN)) return if (istype(user, /mob/living/silicon)) @@ -83,7 +83,8 @@ return /obj/machinery/ai_slipper/Topic(href, href_list) - ..() + if(..()) + return 1 if (src.locked) if (!istype(usr, /mob/living/silicon)) usr << "Control panel is locked!" diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index b2fcd154036..777268f0aef 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -142,8 +142,8 @@ pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24) pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0 update_icon() - if(ticker && ticker.current_state == 3)//if the game is running - src.initialize() + if(ticker && ticker.current_state == GAME_STATE_PLAYING) + initialize() return first_run() @@ -458,6 +458,7 @@ alert_signal.transmission_method = 1 alert_signal.data["zone"] = alarm_area.name alert_signal.data["type"] = "Atmospheric" + alert_signal.data["hidden"] = hidden if(alert_level==2) alert_signal.data["alert"] = "severe" @@ -728,7 +729,39 @@ if(!shorted) ui_interact(user) +/obj/machinery/alarm/proc/can_use(mob/user as mob) + if (user.stat && !isobserver(user)) + user << "\red You must be conscious to use this [src]!" + return 0 + + if(stat & (NOPOWER|BROKEN)) + return 0 + + if(buildstage != 2) + return 0 + + if((get_dist(src, user) > 1) && !istype(user, /mob/living/silicon)) + return 0 + + if(istype(user, /mob/living/silicon) && aidisabled) + user << "AI control for this air alarm interface has been disabled." + return 0 + + return 1 + +/obj/machinery/alarm/proc/is_authenticated(mob/user as mob) + if(isAI(user) || isrobot(user)) + return 1 + else + return !locked + /obj/machinery/alarm/Topic(href, href_list) + if(..()) + return 1 + + if(!can_use(usr)) + return 1 + var/changed=0 if(href_list["rcon"]) @@ -747,6 +780,9 @@ //testing(href) if(href_list["command"]) + if(!is_authenticated(usr)) + return + var/device_id = href_list["id_tag"] switch(href_list["command"]) if( "power", @@ -832,11 +868,17 @@ return 1 if(href_list["screen"]) + if(!is_authenticated(usr)) + return + screen = text2num(href_list["screen"]) ui_interact(usr) return 1 if(href_list["atmos_alarm"]) + if(!is_authenticated(usr)) + return + alarmActivated=1 alarm_area.updateDangerLevel() update_icon() @@ -844,6 +886,9 @@ return 1 if(href_list["atmos_reset"]) + if(!is_authenticated(usr)) + return + alarmActivated=0 alarm_area.updateDangerLevel() update_icon() @@ -851,12 +896,18 @@ return 1 if(href_list["mode"]) + if(!is_authenticated(usr)) + return + mode = text2num(href_list["mode"]) apply_mode() ui_interact(usr) return 1 if(href_list["preset"]) + if(!is_authenticated(usr)) + return + preset = text2num(href_list["preset"]) apply_preset() ui_interact(usr) @@ -879,7 +930,7 @@ updateUsrDialog() -/obj/machinery/alarm/attackby(obj/item/W as obj, mob/user as mob) +/obj/machinery/alarm/attackby(obj/item/W as obj, mob/user as mob, params) /* if (istype(W, /obj/item/weapon/wirecutters)) stat ^= BROKEN add_fingerprint(user) @@ -968,7 +1019,7 @@ playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1) del(src) - return ..() + return 0 /obj/machinery/alarm/power_change() if(powered(power_channel)) @@ -1009,9 +1060,9 @@ Code shamelessly copied from apc_frame desc = "Used for building Air Alarms" icon = 'icons/obj/monitors.dmi' icon_state = "alarm_bitem" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT -/obj/item/alarm_frame/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/alarm_frame/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/wrench)) new /obj/item/stack/sheet/metal( get_turf(src.loc), 2 ) del(src) @@ -1113,7 +1164,7 @@ FIRE ALARM if(prob(50/severity)) alarm() ..() -/obj/machinery/firealarm/attackby(obj/item/W as obj, mob/user as mob) +/obj/machinery/firealarm/attackby(obj/item/W as obj, mob/user as mob, params) src.add_fingerprint(user) if (istype(W, /obj/item/weapon/screwdriver) && buildstage == 2) @@ -1345,9 +1396,9 @@ Code shamelessly copied from apc_frame desc = "Used for building Fire Alarms" icon = 'icons/obj/monitors.dmi' icon_state = "fire_bitem" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT -/obj/item/firealarm_frame/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/firealarm_frame/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/wrench)) new /obj/item/stack/sheet/metal( get_turf(src.loc), 2 ) del(src) diff --git a/code/game/machinery/atmo_control.dm b/code/game/machinery/atmo_control.dm index 1d0cab15733..e6338b824e0 100644 --- a/code/game/machinery/atmo_control.dm +++ b/code/game/machinery/atmo_control.dm @@ -101,7 +101,7 @@ obj/machinery/air_sensor sensors = list() src.updateUsrDialog() - attackby(I as obj, user as mob) + attackby(I as obj, user as mob, params) if(istype(I, /obj/item/weapon/screwdriver)) playsound(get_turf(src), 'sound/items/Screwdriver.ogg', 50, 1) if(do_after(user, 20)) @@ -382,7 +382,7 @@ legend { var/cutoff_temperature = 2000 var/on_temperature = 1200 - attackby(I as obj, user as mob) + attackby(I as obj, user as mob, params) if(istype(I, /obj/item/weapon/screwdriver)) playsound(get_turf(src), 'sound/items/Screwdriver.ogg', 50, 1) if(do_after(user, 20)) diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 580783b6df1..4140d7cdcfe 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -1,59 +1,73 @@ +/datum/canister_icons + var + possiblemaincolor = list( //these lists contain the possible colors of a canister + list("name" = "\[N2O\]", "icon" = "redws"), + list("name" = "\[N2\]", "icon" = "red"), + list("name" = "\[O2\]", "icon" = "blue"), + list("name" = "\[Toxin (Bio)\]", "icon" = "orange"), + list("name" = "\[CO2\]", "icon" = "black"), + list("name" = "\[Air\]", "icon" = "grey"), + list("name" = "\[CAUTION\]", "icon" = "yellow"), + list("name" = "\[SPECIAL\]", "icon" = "whiters") + ) + possibleseccolor = list( // no point in having the N2O and "whiters" ones in these lists + list("name" = "\[N2\]", "icon" = "red-c"), + list("name" = "\[O2\]", "icon" = "blue-c"), + list("name" = "\[Toxin (Bio)\]", "icon" = "orange-c"), + list("name" = "\[CO2\]", "icon" = "black-c"), + list("name" = "\[Air\]", "icon" = "grey-c"), + list("name" = "\[CAUTION\]", "icon" = "yellow-c") + ) + possibletertcolor = list( + list("name" = "\[N2\]", "icon" = "red-c-1"), + list("name" = "\[O2\]", "icon" = "blue-c-1"), + list("name" = "\[Toxin (Bio)\]", "icon" = "orange-c-1"), + list("name" = "\[CO2\]", "icon" = "black-c-1"), + list("name" = "\[Air\]", "icon" = "grey-c-1"), + list("name" = "\[CAUTION\]", "icon" = "yellow-c-1") + ) + possiblequartcolor = list( + list("name" = "\[N2\]", "icon" = "red-c-2"), + list("name" = "\[O2\]", "icon" = "blue-c-2"), + list("name" = "\[Toxin (Bio)\]", "icon" = "orange-c-2"), + list("name" = "\[CO2\]", "icon" = "black-c-2"), + list("name" = "\[Air\]", "icon" = "grey-c-2"), + list("name" = "\[CAUTION\]", "icon" = "yellow-c-2") + ) + + possibledecals = list( //var that stores all possible decals, used by ui + list("name" = "Low temperature canister", "icon" = "cold"), + list("name" = "High temperature canister", "icon" = "hot"), + list("name" = "Plasma containing canister", "icon" = "plasma") + ) + +var/datum/canister_icons/canister_icon_container = new() + /obj/machinery/portable_atmospherics/canister name = "canister" icon = 'icons/obj/atmos.dmi' icon_state = "yellow" density = 1 var/health = 100.0 - flags = FPRINT | CONDUCT - + flags = CONDUCT + + var/menu = 0 + //used by nanoui: 0 = main menu, 1 = relabel + var/valve_open = 0 var/release_pressure = ONE_ATMOSPHERE - - var/list/_color = list("yellow", null, null, null)//variable that stores colours - var/list/decals = list() // var that stores the decals, NOTE: Not the actual POSSIBLE decals, but the ones currently used - var/list/oldcolor = list()//lists for check_change() - var/list/olddecals = list() - var/list/possibledecals = list( //var that stores all possible decals, here for adminbus I guess? NOTE: LEAVE "done" IN HERE - "Low temperature canister" = "cold", - "High temperature canister" = "hot", - "Plasma containing canister" = "plasma", - "Done" = "DONE" - ) - var/list/possiblemaincolor = list( //these lists contain the possible colors of a canister, here for adminbus - "\[N2O\]" = "redws", - "\[N2\]" = "red", - "\[O2\]" = "blue", - "\[Toxin (Bio)\]" = "orange", - "\[CO2\]" = "black", - "\[Air\]" = "grey", - "\[CAUTION\]" = "yellow", - "\[SPECIAL\]" = "whiters" - ) - var/list/possibleseccolor = list( // no point in having the N2O and "whiters" ones in these lists - "\[N2\]" = "red-c", - "\[O2\]" = "blue-c", - "\[Toxin (Bio)\]" = "orange-c", - "\[CO2\]" = "black-c", - "\[Air\]" = "grey-c", - "\[CAUTION\]" = "yellow-c" - ) - var/list/possibletertcolor = list( - "\[N2\]" = "red-c-1", - "\[O2\]" = "blue-c-1", - "\[Toxin (Bio)\]" = "orange-c-1", - "\[CO2\]" = "black-c-1", - "\[Air\]" = "grey-c-1", - "\[CAUTION\]" = "yellow-c-1" - ) - var/list/possiblequartcolor = list( - "\[N2\]" = "red-c-2", - "\[O2\]" = "blue-c-2", - "\[Toxin (Bio)\]" = "orange-c-2", - "\[CO2\]" = "black-c-2", - "\[Air\]" = "grey-c-2", - "\[CAUTION\]" = "yellow-c-2" - ) - + + var/list/_color //variable that stores colours + var/list/decals //list that stores the decals + + //lists for check_change() + var/list/oldcolor + var/list/olddecals + + //passed to the ui to render the color lists + var/list/colorcontainer + var/list/possibledecals + var/can_label = 1 var/filled = 0.5 pressure_resistance = 7*ONE_ATMOSPHERE @@ -63,43 +77,60 @@ var/release_log = "" var/busy = 0 var/update_flag = 0 - -/obj/machinery/portable_atmospherics/canister/sleeping_agent - name = "Canister: \[N2O\]" - icon_state = "redws" - _color = list("redws", null, null, null) - can_label = 0 -/obj/machinery/portable_atmospherics/canister/nitrogen - name = "Canister: \[N2\]" - icon_state = "red" - _color = list("red", null, null, null) - decals = list("plasma") - can_label = 0 -/obj/machinery/portable_atmospherics/canister/oxygen - name = "Canister: \[O2\]" - icon_state = "blue" - _color = list("blue", null, null, null) - can_label = 0 -/obj/machinery/portable_atmospherics/canister/toxins - name = "Canister \[Toxin (Plasma)\]" - icon_state = "orange" - _color = list("orange", null, null, null) - can_label = 0 -/obj/machinery/portable_atmospherics/canister/carbon_dioxide - name = "Canister \[CO2\]" - icon_state = "black" - _color = list("black", null, null, null) - can_label = 0 -/obj/machinery/portable_atmospherics/canister/air - name = "Canister \[Air\]" - icon_state = "grey" - _color = list("grey", null, null, null) - can_label = 0 -/obj/machinery/portable_atmospherics/canister/custom_mix - name = "Canister \[Custom\]" - icon_state = "whiters" - _color = list("whiters", null, null, null) - can_label = 0 + + New() + ..() + _color = list( + "prim" = "yellow", + "sec" = "none", + "ter" = "none", + "quart" = "none") + oldcolor = new /list() + decals = list("cold" = 0, "hot" = 0, "plasma" = 0) + colorcontainer = new /list(4) + possibledecals = new /list(3) + update_icon() + +/obj/machinery/portable_atmospherics/canister/proc/init_data_vars() + //passed to the ui to render the color lists + colorcontainer = list( + "prim" = list( + "options" = canister_icon_container.possiblemaincolor, + "name" = "Primary color", + ), + "sec" = list( + "options" = canister_icon_container.possibleseccolor, + "name" = "Secondary color", + ), + "ter" = list( + "options" = canister_icon_container.possibletertcolor, + "name" = "Tertiary color", + ), + "quart" = list( + "options" = canister_icon_container.possiblequartcolor, + "name" = "Quaternary color", + ) + ) + + //var/anycolor used by the nanoUI, 0: no color applied. 1: color applied + for(var/C in colorcontainer) + if(C == "prim") continue + var/list/L = colorcontainer[C] + if(!(_color[C]) || (_color[C] == "none")) + L.Add(list("anycolor" = 0)) + else + L.Add(list("anycolor" = 1)) + colorcontainer[C] = L + + possibledecals = new /list(3) + + var/i + var/list/L = canister_icon_container.possibledecals + for(i=1;i<=L.len;i++) + var/list/LL = L[i] + LL = LL.Copy() //make sure we don't edit the datum list + LL.Add(list("active" = decals[LL["icon"]])) //"active" used by nanoUI + possibledecals[i] = LL /obj/machinery/portable_atmospherics/canister/proc/check_change() var/old_flag = update_flag @@ -119,11 +150,14 @@ else update_flag |= 32 - if(oldcolor != _color || olddecals != decals) + if(list2params(oldcolor) != list2params(_color)) update_flag |= 64 - olddecals = decals - oldcolor = _color - + oldcolor = _color.Copy() + + if(list2params(olddecals) != list2params(decals)) + update_flag |= 128 + olddecals = decals.Copy() + if(update_flag == old_flag) return 1 else @@ -138,32 +172,31 @@ update_flag 8 = tank_pressure < ONE_ATMOS 16 = tank_pressure < 15*ONE_ATMOS 32 = tank_pressure go boom. -64 = decals/colors got changed +64 = colors +128 = decals +(note: colors and decals has to be applied every icon update) */ if (src.destroyed) src.overlays = 0 - src.icon_state = text("[]-1", src._color[1])//yes, I KNOW the colours don't reflect when the can's borked, whatever. + src.icon_state = text("[]-1", src._color["prim"])//yes, I KNOW the colours don't reflect when the can's borked, whatever. - if(icon_state != src._color[1]) - icon_state = src._color[1] + if(icon_state != src._color["prim"]) + icon_state = src._color["prim"] if(check_change()) //Returns 1 if no change needed to icons. return - src.overlays = 0 - - if (_color[2])//COLORS! - overlays.Add(_color[2]) - - if (_color[3]) - overlays.Add(_color[3]) - - if (_color[4]) - overlays.Add(_color[4]) - + overlays.Cut() + + for(var/C in _color) + if(C == "prim") continue + if(_color[C] == "none") continue + overlays.Add(_color[C]) + for(var/D in decals) - overlays.Add("decal-" + D) + if(decals[D]) + overlays.Add("decal-" + D) if(update_flag & 1) overlays += "can-open" @@ -177,8 +210,36 @@ update_flag overlays += "can-o2" else if(update_flag & 32) overlays += "can-o3" + + update_flag &= ~196 //the flags 128 and 64 represent change, not states. As such, we have to reset them to be able to detect a change on the next go. return +//template modification exploit prevention, used in Topic() +/obj/machinery/portable_atmospherics/canister/proc/is_a_color(var/inputVar, var/checkColor = "all") + if (checkColor == "prim" || checkColor == "all") + for(var/list/L in canister_icon_container.possiblemaincolor) + if (L["icon"] == inputVar) + return 1 + if (checkColor == "sec" || checkColor == "all") + for(var/list/L in canister_icon_container.possibleseccolor) + if (L["icon"] == inputVar) + return 1 + if (checkColor == "ter" || checkColor == "all") + for(var/list/L in canister_icon_container.possibletertcolor) + if (L["icon"] == inputVar) + return 1 + if (checkColor == "quart" || checkColor == "all") + for(var/list/L in canister_icon_container.possiblequartcolor) + if (L["icon"] == inputVar) + return 1 + return 0 + +/obj/machinery/portable_atmospherics/canister/proc/is_a_decal(var/inputVar) + for(var/list/L in canister_icon_container.possibledecals) + if (L["icon"] == inputVar) + return 1 + return 0 + /obj/machinery/portable_atmospherics/canister/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) if(exposed_temperature > temperature_resistance) health -= 5 @@ -276,7 +337,7 @@ update_flag healthcheck() return -/obj/machinery/portable_atmospherics/canister/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) +/obj/machinery/portable_atmospherics/canister/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params) if(iswelder(W) && src.destroyed) if(weld(W, user)) user << "\blue You salvage whats left of \the [src]" @@ -327,10 +388,16 @@ update_flag if (src.destroyed) return + init_data_vars() //set up var/colorcontainer and var/possibledecals + // this is the data which will be sent to the ui var/data[0] data["name"] = name + data["menu"] = menu ? 1 : 0 data["canLabel"] = can_label ? 1 : 0 + data["_color"] = _color + data["colorContainer"] = colorcontainer + data["possibleDecals"] = possibledecals data["portConnected"] = connected_port ? 1 : 0 data["tankPressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0) data["releasePressure"] = round(release_pressure ? release_pressure : 0) @@ -354,6 +421,10 @@ update_flag ui.open() // auto update every Master Controller tick ui.set_auto_update(1) + + //Disregard these, avoid cluttering up the VV window + colorcontainer = new /list(4) + possibledecals = new /list(3) /obj/machinery/portable_atmospherics/canister/Topic(href, href_list) @@ -365,6 +436,9 @@ update_flag usr << browse(null, "window=canister") onclose(usr, "canister") return + + if (href_list["choice"] == "menu") + menu = text2num(href_list["mode_target"]) if(href_list["toggle"]) if (valve_open) @@ -393,49 +467,82 @@ update_flag release_pressure = min(10*ONE_ATMOSPHERE, release_pressure+diff) else release_pressure = max(ONE_ATMOSPHERE/10, release_pressure+diff) - - if (href_list["relabel"]) + + if (href_list["rename"]) if (can_label) + var/T = sanitize(copytext(input("Choose canister label", "Name", name) as text|null,1,MAX_NAME_LEN)) + if (can_label) //Exploit prevention + if (T) + name = T + else + name = "canister" + else + usr << "\red As you attempted to rename it the pressure rose!" - var/label1 = input("Choose canister label", "Primary color") as null|anything in possiblemaincolor - - var/label2 = input("Choose canister label", "Secondary color") as null|anything in possibleseccolor - - var/label3 = input("Choose canister label", "Tertiary color") as null|anything in possibletertcolor - - var/label4 = input("Choose canister label", "Quaternary color") as null|anything in possiblequartcolor - - decals = list() - - _color = list( - (label1 ? possiblemaincolor[label1] : color[1]),//if the user didn't specify a primary colour, keep the current one. - possibleseccolor[label2], - possibletertcolor[label3], - possiblequartcolor[label4] - ) - - decals = list() - - var/list/tempposdecals = possibledecals - while (src && !src.gc_destroyed && usr)//allow the user to select (theoretically) INFINITE DECALS!!! - var/newdecal = input("Choose canister label", "Decal") as anything in tempposdecals - if (newdecal == "Done") - break - decals.Add(tempposdecals[newdecal]) - tempposdecals.Remove(newdecal) - - src.name = (input("Choose canister label", "Name") as text) + " canister" - - + if (href_list["choice"] == "Primary color") + if (is_a_color(href_list["icon"],"prim")) + _color["prim"] = href_list["icon"] + if (href_list["choice"] == "Secondary color") + if (href_list["icon"] == "none") + _color["sec"] = "none" + else if (is_a_color(href_list["icon"],"sec")) + _color["sec"] = href_list["icon"] + if (href_list["choice"] == "Tertiary color") + if (href_list["icon"] == "none") + _color["ter"] = "none" + else if (is_a_color(href_list["icon"],"ter")) + _color["ter"] = href_list["icon"] + if (href_list["choice"] == "Quaternary color") + if (href_list["icon"] == "none") + _color["quart"] = "none" + else if (is_a_color(href_list["icon"],"quart")) + _color["quart"] = href_list["icon"] + + if (href_list["choice"] == "decals") + if (is_a_decal(href_list["icon"])) + decals[href_list["icon"]] = (decals[href_list["icon"]] == 0) + src.add_fingerprint(usr) update_icon() return 1 + +/obj/machinery/portable_atmospherics/canister/toxins + name = "Canister \[Toxin (Plasma)\]" + icon_state = "orange" //See New() + can_label = 0 +/obj/machinery/portable_atmospherics/canister/oxygen + name = "Canister: \[O2\]" + icon_state = "blue" //See New() + can_label = 0 +/obj/machinery/portable_atmospherics/canister/sleeping_agent + name = "Canister: \[N2O\]" + icon_state = "redws" //See New() + can_label = 0 +/obj/machinery/portable_atmospherics/canister/nitrogen + name = "Canister: \[N2\]" + icon_state = "red" //See New() + can_label = 0 +/obj/machinery/portable_atmospherics/canister/carbon_dioxide + name = "Canister \[CO2\]" + icon_state = "black" //See New() + can_label = 0 +/obj/machinery/portable_atmospherics/canister/air + name = "Canister \[Air\]" + icon_state = "grey" //See New() + can_label = 0 +/obj/machinery/portable_atmospherics/canister/custom_mix + name = "Canister \[Custom\]" + icon_state = "whiters" //See New() + can_label = 0 + + /obj/machinery/portable_atmospherics/canister/toxins/New() - ..() - + + _color["prim"] = "orange" + decals["plasma"] = 1 src.air_contents.toxins = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) air_contents.update_values() @@ -443,18 +550,18 @@ update_flag return 1 /obj/machinery/portable_atmospherics/canister/oxygen/New() - ..() + _color["prim"] = "blue" src.air_contents.oxygen = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) air_contents.update_values() src.update_icon() return 1 /obj/machinery/portable_atmospherics/canister/sleeping_agent/New() - ..() - + + _color["prim"] = "redws" var/datum/gas/sleeping_agent/trace_gas = new air_contents.trace_gases += trace_gas trace_gas.moles = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) @@ -480,9 +587,9 @@ update_flag /obj/machinery/portable_atmospherics/canister/nitrogen/New() - ..() + _color["prim"] = "red" src.air_contents.nitrogen = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) air_contents.update_values() @@ -490,8 +597,9 @@ update_flag return 1 /obj/machinery/portable_atmospherics/canister/carbon_dioxide/New() - ..() + + _color["prim"] = "black" src.air_contents.carbon_dioxide = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) air_contents.update_values() @@ -500,8 +608,9 @@ update_flag /obj/machinery/portable_atmospherics/canister/air/New() - ..() + + _color["prim"] = "grey" src.air_contents.oxygen = (O2STANDARD*src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) src.air_contents.nitrogen = (N2STANDARD*src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) air_contents.update_values() @@ -512,6 +621,7 @@ update_flag /obj/machinery/portable_atmospherics/canister/custom_mix/New() ..() + _color["prim"] = "whiters" src.update_icon() // Otherwise new canisters do not have their icon updated with the pressure light, likely want to add this to the canister class constructor, avoiding at current time to refrain from screwing up code for other canisters. --DZD return 1 diff --git a/code/game/machinery/atmoalter/meter.dm b/code/game/machinery/atmoalter/meter.dm index 42518697027..3da432b94f3 100644 --- a/code/game/machinery/atmoalter/meter.dm +++ b/code/game/machinery/atmoalter/meter.dm @@ -24,23 +24,15 @@ /obj/machinery/meter/process() if(!target) icon_state = "meterX" - // Pop the meter off when the pipe we're attached to croaks. - new /obj/item/pipe_meter(src.loc) - spawn(0) del(src) return 0 if(stat & (BROKEN|NOPOWER)) icon_state = "meter0" return 0 - //use_power(5) - var/datum/gas_mixture/environment = target.return_air() if(!environment) icon_state = "meterX" - // Pop the meter off when the environment we're attached to croaks. - new /obj/item/pipe_meter(src.loc) - spawn(0) del(src) return 0 var/env_pressure = environment.return_pressure() @@ -87,30 +79,33 @@ return t /obj/machinery/meter/examine() - set src in view(3) - var/t = "A gas flow meter. " - t += status() + + if(get_dist(usr, src) > 3 && !(istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/dead))) + t += "\blue You are too far away to read it." + + else if(stat & (NOPOWER|BROKEN)) + t += "\red The display is off." + + else if(src.target) + var/datum/gas_mixture/environment = target.return_air() + if(environment) + t += "The pressure gauge reads [round(environment.return_pressure(), 0.01)] kPa; [round(environment.temperature,0.01)]K ([round(environment.temperature-T0C,0.01)]°C)" + else + t += "The sensor error light is blinking." + else + t += "The connect error light is blinking." + usr << t - - /obj/machinery/meter/Click() - - if(stat & (NOPOWER|BROKEN)) + if(istype(usr, /mob/living/silicon/ai)) // ghosts can call ..() for examine + usr.examine(src) return 1 + + return ..() - var/t = null - if (get_dist(usr, src) <= 3 || istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/dead)) - t += status() - else - usr << "\blue You are too far away." - return 1 - - usr << t - return 1 - -/obj/machinery/meter/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) +/obj/machinery/meter/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params) if (!istype(W, /obj/item/weapon/wrench)) return ..() playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) @@ -135,5 +130,5 @@ if (!target) src.target = loc -/obj/machinery/meter/turf/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) +/obj/machinery/meter/turf/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params) return diff --git a/code/game/machinery/atmoalter/portable_atmospherics.dm b/code/game/machinery/atmoalter/portable_atmospherics.dm index ea319bf2e32..ed56300120d 100644 --- a/code/game/machinery/atmoalter/portable_atmospherics.dm +++ b/code/game/machinery/atmoalter/portable_atmospherics.dm @@ -82,7 +82,7 @@ return 1 -/obj/machinery/portable_atmospherics/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) +/obj/machinery/portable_atmospherics/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params) var/obj/icon = src if ((istype(W, /obj/item/weapon/tank) && !( src.destroyed ))) if (src.holding) diff --git a/code/game/machinery/atmoalter/scrubber.dm b/code/game/machinery/atmoalter/scrubber.dm index 08c1d42b9ed..4821ef4f15b 100644 --- a/code/game/machinery/atmoalter/scrubber.dm +++ b/code/game/machinery/atmoalter/scrubber.dm @@ -48,7 +48,7 @@ else icon_state = "scrubber:0" - attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) + attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params) if(istype(W, /obj/item/weapon/wrench)) if(on) user << "\blue Turn it off first!" @@ -65,7 +65,7 @@ /obj/machinery/portable_atmospherics/scrubber/huge/stationary name = "Stationary Air Scrubber" - attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) + attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params) if(istype(W, /obj/item/weapon/wrench)) user << "\blue The bolts are too tight for you to unscrew!" return diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index df7e75bc1c4..6c13db51ad5 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -1,3 +1,7 @@ +#define AUTOLATHE_MAIN_MENU 1 +#define AUTOLATHE_CATEGORY_MENU 2 +#define AUTOLATHE_SEARCH_MENU 3 + /obj/machinery/autolathe name = "autolathe" desc = "It produces items using metal and glass." @@ -11,6 +15,9 @@ var/max_g_amount = 75000.0 var/operating = 0.0 + var/list/queue = list() + var/queue_max_len = 12 + var/turf/BuildTurf anchored = 1.0 var/list/L = list() var/list/LL = list() @@ -27,8 +34,9 @@ var/prod_coeff var/datum/wires/autolathe/wires = null - var/datum/design/being_built + var/list/being_built = list() var/datum/research/files + var/list/datum/design/matching_designs var/selected_category var/screen = 1 @@ -39,7 +47,7 @@ "Medical", "Miscellaneous", "Security", - "Tools" + "Tools" ) /obj/machinery/autolathe/New() @@ -55,7 +63,8 @@ wires = new(src) files = new /datum/research/autolathe(src) - + matching_designs = list() + /obj/machinery/autolathe/upgraded/New() ..() component_parts = list() @@ -66,7 +75,7 @@ component_parts += new /obj/item/weapon/stock_parts/manipulator/pico(null) component_parts += new /obj/item/weapon/stock_parts/console_screen(null) RefreshParts() - + /obj/machinery/autolathe/interact(mob/user) if(shocked && !(stat & NOPOWER)) shock(user,50) @@ -78,18 +87,21 @@ dat = wires.GetInteractWindow() else - if(screen == 1) - dat = main_win(user) - else - dat += category_win(user,selected_category) + switch(screen) + if(AUTOLATHE_MAIN_MENU) + dat = main_win(user) + if(AUTOLATHE_CATEGORY_MENU) + dat = category_win(user,selected_category) + if(AUTOLATHE_SEARCH_MENU) + dat = search_win(user) - var/datum/browser/popup = new(user, "autolathe", name, 500, 500) + var/datum/browser/popup = new(user, "autolathe", name, 800, 500) popup.set_content(dat) popup.open() return -/obj/machinery/autolathe/attackby(obj/item/O, mob/user) +/obj/machinery/autolathe/attackby(obj/item/O, mob/user, params) if (busy) user << "The autolathe is busy. Please wait for completion of previous operation." return 1 @@ -142,7 +154,7 @@ flick("autolathe_r",src)//plays glass insertion animation stack.use(amount) else - if(!user.before_take_item(O)) + if(!user.unEquip(O)) user << "/the [O] is stuck to your hand, you can't put it in \the [src]!" O.loc = src icon_state = "autolathe" @@ -166,67 +178,64 @@ /obj/machinery/autolathe/Topic(href, href_list) if(..()) - return - if (!busy) - if(href_list["menu"]) - screen = text2num(href_list["menu"]) + return 1 + if(href_list["menu"]) + screen = text2num(href_list["menu"]) - if(href_list["category"]) - selected_category = href_list["category"] + if(href_list["category"]) + selected_category = href_list["category"] - if(href_list["make"]) + if(href_list["make"]) + BuildTurf = get_step(src.loc, get_dir(src,usr)) - var/turf/T = get_step(src.loc, get_dir(src,usr)) + ///////////////// + //href protection + var/datum/design/design_last_ordered + design_last_ordered = files.FindDesignByID(href_list["make"]) //check if it's a valid design + if(!design_last_ordered) + return + if(!(design_last_ordered.build_type & AUTOLATHE)) + return - ///////////////// - //href protection - being_built = files.FindDesignByID(href_list["make"]) //check if it's a valid design - if(!being_built) - return + //multiplier checks : only stacks can have one and its value is 1, 10 ,25 or max_multiplier + var/multiplier = text2num(href_list["multiplier"]) + var/max_multiplier = min(50, design_last_ordered.materials["$metal"] ?round(m_amount/design_last_ordered.materials["$metal"]):INFINITY,design_last_ordered.materials["$glass"]?round(g_amount/design_last_ordered.materials["$glass"]):INFINITY) + var/is_stack = ispath(design_last_ordered.build_path, /obj/item/stack) - //multiplier checks : only stacks can have one and its value is 1, 10 ,25 or max_multiplier - var/multiplier = text2num(href_list["multiplier"]) - var/max_multiplier = min(50, being_built.materials["$metal"] ?round(m_amount/being_built.materials["$metal"]):INFINITY,being_built.materials["$glass"]?round(g_amount/being_built.materials["$glass"]):INFINITY) - var/is_stack = ispath(being_built.build_path, /obj/item/stack) + if(!is_stack && (multiplier > 1)) + return + if (!(multiplier in list(1,10,25,max_multiplier))) //"enough materials ?" is checked in the build proc + return + ///////////////// - if(!is_stack && (multiplier > 1)) - return - if (!(multiplier in list(1,10,25,max_multiplier))) //"enough materials ?" is checked further down - return - ///////////////// + if((queue.len+1)= metal_cost*multiplier/coeff) && (g_amount >= glass_cost*multiplier/coeff)) - busy = 1 - use_power(power) - icon_state = "autolathe" - flick("autolathe_n",src) - spawn(32/coeff) - use_power(power) - if(is_stack) - m_amount -= metal_cost*multiplier - g_amount -= glass_cost*multiplier - var/obj/item/stack/S = new being_built.build_path(T) - S.amount = multiplier - else - m_amount -= metal_cost/coeff - g_amount -= glass_cost/coeff - var/obj/item/new_item = new being_built.build_path(T) - new_item.m_amt /= coeff - new_item.g_amt /= coeff - if(m_amount < 0) - m_amount = 0 - if(g_amount < 0) - g_amount = 0 - busy = 0 - src.updateUsrDialog() - else - usr << "The autolathe is busy. Please wait for completion of previous operation." src.updateUsrDialog() @@ -243,10 +252,165 @@ for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) prod_coeff += M.rating - 1 +/obj/machinery/autolathe/proc/get_coeff(var/datum/design/D) + var/coeff = (ispath(D.build_path,/obj/item/stack) ? 1 : 2 ** prod_coeff)//stacks are unaffected by production coefficient + return coeff + +/obj/machinery/autolathe/proc/build_item(var/datum/design/D, var/multiplier) + desc = initial(desc)+"\nIt's building \a [initial(D.name)]." + var/is_stack = ispath(D.build_path, /obj/item/stack) + var/coeff = get_coeff(D) + var/metal_cost = D.materials["$metal"] + var/glass_cost = D.materials["$glass"] + var/power = max(2000, (metal_cost+glass_cost)*multiplier/5) + if (can_build(D,multiplier)) + being_built = list(D,multiplier) + use_power(power) + icon_state = "autolathe" + flick("autolathe_n",src) + if(is_stack) + m_amount -= metal_cost*multiplier + g_amount -= glass_cost*multiplier + else + m_amount -= metal_cost/coeff + g_amount -= glass_cost/coeff + updateUsrDialog() + sleep(32/coeff) + if(is_stack) + var/obj/item/stack/S = new D.build_path(BuildTurf) + S.amount = multiplier + else + var/obj/item/new_item = new D.build_path(BuildTurf) + new_item.m_amt /= coeff + new_item.g_amt /= coeff + if(m_amount < 0) + m_amount = 0 + if(g_amount < 0) + g_amount = 0 + updateUsrDialog() + desc = initial(desc) + +/obj/machinery/autolathe/proc/can_build(var/datum/design/D,var/multiplier=1,var/custom_metal,var/custom_glass) + var/coeff = get_coeff(D) + + var/metal_amount = m_amount + if(custom_metal) + metal_amount = custom_metal + var/glass_amount = g_amount + if(custom_glass) + glass_amount = custom_glass + + if(D.materials["$metal"] && (metal_amount < (multiplier*D.materials["$metal"] / coeff))) + return 0 + if(D.materials["$glass"] && (glass_amount < (multiplier*D.materials["$glass"] / coeff))) + return 0 + return 1 + +/obj/machinery/autolathe/proc/get_design_cost_as_list(var/datum/design/D,var/multiplier=1) + var/list/OutputList = list(0,0) + var/coeff = get_coeff(D) + if(D.materials["$metal"]) + OutputList[1] = (D.materials["$metal"] / coeff)*multiplier + if(D.materials["$glass"]) + OutputList[2] = (D.materials["$glass"] / coeff)*multiplier + return OutputList + +/obj/machinery/autolathe/proc/get_processing_line() + var/datum/design/D = being_built[1] + var/multiplier = being_built[2] + var/is_stack = (multiplier>1) + var/output = "PROCESSING: [initial(D.name)][is_stack?" (x[multiplier])":null]" + return output + +/obj/machinery/autolathe/proc/get_queue() + var/temp_metal = m_amount + var/temp_glass = g_amount + var/output = "" + output += "
" + output += "Queue contains:" + if (!istype(queue) || !queue.len) + if(being_built.len) + output += "
  1. " + output += get_processing_line() + output += "
" + else + output += "
Nothing" + else + output += "
    " + if(being_built.len) + output += "
  1. " + output += get_processing_line() + output += "
  2. " + var/i = 0 + var/datum/design/D + for(var/list/L in queue) + i++ + D = L[1] + var/multiplier = L[2] + var/list/LL = get_design_cost_as_list(D,multiplier) + var/is_stack = (multiplier>1) + output += "[initial(D.name)][is_stack?" (x[multiplier])":null] - [i>1?"":null] [i↓":null] Remove" + temp_metal = max(temp_metal-LL[1],1) + temp_glass = max(temp_glass-LL[2],1) + + output += "
" + output += "Clear queue" + output += "
" + return output + +/obj/machinery/autolathe/proc/add_to_queue(D,var/multiplier) + if(!istype(queue)) + queue = list() + if(D) + queue.Add(list(list(D,multiplier))) + return queue.len + +/obj/machinery/autolathe/proc/remove_from_queue(index) + if(!isnum(index) || !istype(queue) || (index<1 || index>queue.len)) + return 0 + queue.Cut(index,++index) + return 1 + +/obj/machinery/autolathe/proc/process_queue() + var/datum/design/D = queue[1][1] + var/multiplier = queue[1][2] + if(!D) + remove_from_queue(1) + if(queue.len) + return process_queue() + else + return + while(D) + if(stat&(NOPOWER|BROKEN)) + being_built = new /list() + return 0 + if(!can_build(D,multiplier)) + visible_message("\icon[src] \The [src] beeps, \"Not enough resources. Queue processing terminated.\"") + queue = list() + being_built = new /list() + return 0 + + remove_from_queue(1) + build_item(D,multiplier) + D = listgetindex(listgetindex(queue, 1),1) + multiplier = listgetindex(listgetindex(queue,1),2) + being_built = new /list() + //visible_message("\icon[src] \The [src] beeps, \"Queue processing finished successfully.\"") + /obj/machinery/autolathe/proc/main_win(mob/user) - var/dat = "

Autolathe Menu:


" + var/dat = "" + dat += "" + dat += get_queue() + dat += "
" + dat += "

Autolathe Menu:


" dat += "Metal amount: [src.m_amount] / [max_m_amount] cm3
" - dat += "Glass amount: [src.g_amount] / [max_g_amount] cm3
" + dat += "Glass amount: [src.g_amount] / [max_g_amount] cm3" + + dat += "
\ + \ + \ + \ + \ + \ +

" var/line_length = 1 dat += "" @@ -256,15 +420,20 @@ dat += "" line_length = 1 - dat += "" + dat += "" line_length++ dat += "
[C][C]
" + dat += "
" return dat /obj/machinery/autolathe/proc/category_win(mob/user,var/selected_category) - var/dat = "Return to category screen" - dat += "

Browsing [selected_category]:


" + var/dat = "" + dat += get_queue() + dat += "
" + dat += "
" + dat += "Return to main menu" + dat += "

Browsing [selected_category]:


" dat += "Metal amount: [src.m_amount] / [max_m_amount] cm3
" dat += "Glass amount: [src.g_amount] / [max_g_amount] cm3
" @@ -289,19 +458,44 @@ dat += "[get_design_cost(D)]
" dat += "
" + dat += "
" return dat -/obj/machinery/autolathe/proc/can_build(var/datum/design/D) - var/coeff = (ispath(D.build_path,/obj/item/stack) ? 1 : 2 ** prod_coeff) +/obj/machinery/autolathe/proc/search_win(mob/user) + var/dat = "" + dat += get_queue() + dat += "
" + dat += "
" + dat += "Return to main menu" + dat += "

Search results:


" + dat += "Metal amount: [src.m_amount] / [max_m_amount] cm3
" + dat += "Glass amount: [src.g_amount] / [max_g_amount] cm3
" - if(D.materials["$metal"] && (m_amount < (D.materials["$metal"] / coeff))) - return 0 - if(D.materials["$glass"] && (g_amount < (D.materials["$glass"] / coeff))) - return 0 - return 1 + for(var/datum/design/D in matching_designs) + if(disabled || !can_build(D)) + dat += "[D.name]" + else + dat += "[D.name]" + + if(ispath(D.build_path, /obj/item/stack)) + var/max_multiplier = min(50, D.materials["$metal"] ?round(m_amount/D.materials["$metal"]):INFINITY,D.materials["$glass"]?round(g_amount/D.materials["$glass"]):INFINITY) + if (max_multiplier>10 && !disabled) + dat += " x10" + if (max_multiplier>25 && !disabled) + dat += " x25" + if(max_multiplier > 0 && !disabled) + dat += " x[max_multiplier]" + + dat += "[get_design_cost(D)]
" + + dat += "
" + dat += "
" + return dat /obj/machinery/autolathe/proc/get_design_cost(var/datum/design/D) - var/coeff = (ispath(D.build_path,/obj/item/stack) ? 1 : 2 ** prod_coeff) + var/coeff = get_coeff(D) var/dat if(D.materials["$metal"]) dat += "[D.materials["$metal"] / coeff] metal " @@ -327,7 +521,7 @@ if(hack) for(var/datum/design/D in files.possible_designs) - if((D.build_type & 4) && ("hacked" in D.category)) + if((D.build_type & AUTOLATHE) && ("hacked" in D.category)) files.known_designs += D else for(var/datum/design/D in files.known_designs) diff --git a/code/game/machinery/bees_apiary.dm b/code/game/machinery/bees_apiary.dm index d4e6aa6307e..9021c4ba84d 100644 --- a/code/game/machinery/bees_apiary.dm +++ b/code/game/machinery/bees_apiary.dm @@ -43,7 +43,7 @@ ..() return -/obj/machinery/apiary/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/machinery/apiary/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(istype(O, /obj/item/queen_bee)) if(health > 0) user << "\red There is already a queen in there." diff --git a/code/game/machinery/bees_items.dm b/code/game/machinery/bees_items.dm index 01ed5bfa407..01e5d96ac02 100644 --- a/code/game/machinery/bees_items.dm +++ b/code/game/machinery/bees_items.dm @@ -65,7 +65,6 @@ name = "bottle of BeezEez" icon = 'icons/obj/chemical.dmi' icon_state = "bottle17" - flags = FPRINT | TABLEPASS New() src.pixel_x = rand(-5.0, 5) src.pixel_y = rand(-5.0, 5) diff --git a/code/game/machinery/biogenerator.dm b/code/game/machinery/biogenerator.dm index f834719c9e0..bf53df74ecf 100644 --- a/code/game/machinery/biogenerator.dm +++ b/code/game/machinery/biogenerator.dm @@ -50,17 +50,17 @@ icon_state = "biogen-work" return -/obj/machinery/biogenerator/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/machinery/biogenerator/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(istype(O, /obj/item/weapon/reagent_containers/glass) && !panel_open) if(beaker) user << "A container is already loaded into the machine." else - user.before_take_item(O) + user.unEquip(O) O.loc = src beaker = O user << "You add the container to the machine." updateUsrDialog() - + if(!processing) if(default_deconstruction_screwdriver(user, "biogen-empty-o", "biogen-empty", O)) if(beaker) @@ -72,7 +72,7 @@ if(exchange_parts(user, O)) return - else if(istype(O, /obj/item/weapon/crowbar)) + else if(istype(O, /obj/item/weapon/crowbar)) else if(panel_open) user << "Close the maintenance panel first." else if(processing) @@ -105,13 +105,13 @@ if(i >= 10) user << "The biogenerator is full! Activate it." else - user.before_take_item(O) + user.unEquip(O) O.loc = src user << "You put [O.name] in [src.name]" - default_deconstruction_crowbar(O) - + default_deconstruction_crowbar(O) + update_icon() return @@ -246,14 +246,14 @@ if(in_beaker) if(check_container_volume(10)) return 0 else beaker.reagents.add_reagent("left4zed",10) - else + else new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(src.loc) if("rh") if (check_cost(25/efficiency)) return 0 if(in_beaker) if(check_container_volume(10)) return 0 else beaker.reagents.add_reagent("robustharvest",10) - else + else new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(src.loc) if("wallet") if (check_cost(100/efficiency)) return 0 @@ -298,7 +298,7 @@ /obj/machinery/biogenerator/Topic(href, href_list) if(..() || panel_open) - return + return 1 usr.set_machine(src) @@ -324,7 +324,7 @@ else if(href_list["menu"]) menustat = "menu" updateUsrDialog() - + else if(href_list["inbeaker"]) in_beaker = !in_beaker updateUsrDialog() \ No newline at end of file diff --git a/code/game/machinery/bots/bots.dm b/code/game/machinery/bots/bots.dm index 539dd775b0f..89281d06dcd 100644 --- a/code/game/machinery/bots/bots.dm +++ b/code/game/machinery/bots/bots.dm @@ -29,7 +29,6 @@ var/remote_disabled = 0 //If enabled, the AI cannot *Remotely* control a bot. It can still control it through cameras. var/mob/living/silicon/ai/calling_ai //Links a bot to the AI calling it. var/obj/item/device/radio/Radio //The bot's radio, for speaking to people. - var/radio_frequency //The bot's default radio speaking freqency. Recommended to be on a department frequency. var/radio_name = "Common" //var/emagged = 0 //Urist: Moving that var to the general /bot tree as it's used by most bots var/auto_patrol = 0// set to make bot automatically patrol @@ -146,6 +145,8 @@ user << "[src] is in pristine condition." /obj/machinery/bot/attack_alien(var/mob/living/carbon/alien/user as mob) + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) health -= rand(15,30)*brute_dam_coeff visible_message("[user] has slashed [src]!") playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1) @@ -155,6 +156,7 @@ /obj/machinery/bot/attack_animal(var/mob/living/simple_animal/M as mob) + M.do_attack_animation(src) if(M.melee_damage_upper == 0) return health -= M.melee_damage_upper @@ -230,15 +232,13 @@ return 1 //Successful completion. Used to prevent child process() continuing if this one is ended early. -/obj/machinery/bot/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/bot/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/screwdriver)) if(!locked) open = !open user << "Maintenance panel is now [open ? "opened" : "closed"]." else user << "Maintenance panel is locked." - else if (istype(W, /obj/item/weapon/card/emag) && emagged < 2) - Emag(user) else if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != "harm") if(health >= maxhealth) @@ -267,7 +267,10 @@ ..() healthcheck() - +/obj/machinery/bot/emag_act(user as mob) + if (emagged < 2) + Emag(user) + /obj/machinery/bot/bullet_act(var/obj/item/projectile/Proj) if((Proj.damage_type == BRUTE || Proj.damage_type == BURN)) health -= Proj.damage @@ -338,11 +341,9 @@ /obj/machinery/bot/attack_ai(mob/user as mob) attack_hand(user) -/obj/machinery/bot/proc/speak(var/message, freq, var/freqname = null) //Pass a message to have the bot say() it. Pass a frequency to say it on the radio. +/obj/machinery/bot/proc/speak(var/message, var/freqname = null) //Pass a message to have the bot say() it. Pass a frequency to say it on the radio. if((!on) || (!message)) return - if(freq) - Radio.set_frequency(radio_frequency) if(freqname) Radio.autosay(message, src.name, freqname, list(src.z)) else @@ -373,6 +374,8 @@ obj/machinery/bot/proc/scan(var/scan_type, var/old_target, var/scan_range) final_result = scan_result else continue //The current element failed assessment, move on to the next. + else + continue return final_result //When the scan finds a target, run bot specific processing to select it for the next step. Empty by default. @@ -583,7 +586,7 @@ obj/machinery/bot/proc/start_patrol() new_destination = "__nearest__" post_signal(beacon_freq, "findbeacon", "patrol") awaiting_beacon = 1 - spawn(150) + spawn(200) awaiting_beacon = 0 if(nearest_beacon) set_destination(nearest_beacon) @@ -653,7 +656,7 @@ obj/machinery/bot/proc/start_patrol() botcard.access = user_access + prev_access //Adds the user's access, if any. mode = BOT_SUMMON calc_summon_path() - speak("Responding.", radio_frequency, radio_name) + speak("Responding.", radio_name) return // receive response from beacon @@ -740,7 +743,7 @@ obj/machinery/bot/proc/bot_summon() check_bot_access() path = AStar(loc, summon_target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_cardinal, 0, 150, id=botcard, exclude=avoid) if(!path || tries >= 5) //Cannot reach target. Give up and announce the issue. - speak("Summon command failed, destination unreachable.", radio_frequency, radio_name) + speak("Summon command failed, destination unreachable.", radio_name) bot_reset() /obj/machinery/bot/proc/summon_step() diff --git a/code/game/machinery/bots/cleanbot.dm b/code/game/machinery/bots/cleanbot.dm index 5c4d3bf9200..7bd66b6838f 100644 --- a/code/game/machinery/bots/cleanbot.dm +++ b/code/game/machinery/bots/cleanbot.dm @@ -38,7 +38,6 @@ var/failed_steps var/next_dest var/next_dest_loc - radio_frequency = SRV_FREQ //Service radio_name = "Service" bot_type = CLEAN_BOT bot_type_name = "Cleanbot" @@ -117,7 +116,7 @@ text("[on ? "On" : "Off"]")) beacon_freq = freq updateUsrDialog() -/obj/machinery/bot/cleanbot/attackby(obj/item/weapon/W, mob/user as mob) +/obj/machinery/bot/cleanbot/attackby(obj/item/weapon/W, mob/user as mob, params) if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) if(allowed(usr) && !open && !emagged) locked = !locked @@ -263,7 +262,7 @@ text("[on ? "On" : "Off"]")) qdel(src) return -/obj/item/weapon/bucket_sensor/attackby(var/obj/item/W, mob/user as mob) +/obj/item/weapon/bucket_sensor/attackby(var/obj/item/W, mob/user as mob, params) ..() if(istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm)) user.drop_item() @@ -272,7 +271,7 @@ text("[on ? "On" : "Off"]")) var/obj/machinery/bot/cleanbot/A = new /obj/machinery/bot/cleanbot(T) A.name = created_name user << "You add the robot arm to the bucket and sensor assembly. Beep boop!" - user.before_take_item(src, 1) + user.unEquip(src, 1) qdel(src) else if (istype(W, /obj/item/weapon/pen)) diff --git a/code/game/machinery/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm index 6fb65f8a705..2c9055e29c4 100644 --- a/code/game/machinery/bots/ed209bot.dm +++ b/code/game/machinery/bots/ed209bot.dm @@ -33,7 +33,6 @@ var/arrest_type = 0 //If true, don't handcuff var/projectile = /obj/item/projectile/energy/electrode //Holder for projectile type var/shoot_sound = 'sound/weapons/Taser.ogg' - radio_frequency = SEC_FREQ radio_name = "Security" bot_type = SEC_BOT bot_type_name = "ED-209" @@ -171,7 +170,7 @@ Auto Patrol[]"}, declare_arrests = !declare_arrests updateUsrDialog() -/obj/machinery/bot/ed209/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/bot/ed209/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) if (allowed(user) && !open && !emagged) locked = !locked @@ -258,7 +257,7 @@ Auto Patrol[]"}, icon_state = "[lasercolor]ed209[on]" var/mob/living/carbon/M = target if(istype(M, /mob/living/carbon/human)) - if( M.stuttering < 5 && !(M_HULK in M.mutations) ) + if( M.stuttering < 5 && !(HULK in M.mutations) ) M.stuttering = 5 M.Stun(5) M.Weaken(5) @@ -269,7 +268,7 @@ Auto Patrol[]"}, if(declare_arrests) var/area/location = get_area(src) - speak("[arrest_type ? "Detaining" : "Arresting"] level [threatlevel] scumbag [target] in [location].",radio_frequency, radio_name) + speak("[arrest_type ? "Detaining" : "Arresting"] level [threatlevel] scumbag [target] in [location].", radio_name) target.visible_message("[target] has been stunned by [src]!",\ "[target] has been stunned by [src]!") @@ -299,16 +298,15 @@ Auto Patrol[]"}, if(!arrest_type) if(!target.handcuffed) //he's not cuffed? Try to cuff him! mode = BOT_ARREST - playsound(loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2) - target.visible_message("[src] is trying to put handcuffs on [target]!",\ - "[src] is trying to put handcuffs on [target]!") - + playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) + target.visible_message("[src] is trying to put zipties on [target]!",\ + "[src] is trying to put zipties on [target]!") spawn(30) if( !Adjacent(target) || !isturf(target.loc) ) //if he's in a closet or not adjacent, we cancel cuffing. return if(!target.handcuffed) - target.handcuffed = new /obj/item/weapon/handcuffs(target) - target.update_inv_handcuffed(0) //update the handcuffs overlay + target.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(target) + target.update_inv_handcuffed(1) //update the handcuffs overlay back_to_idle() else back_to_idle() @@ -540,7 +538,7 @@ Auto Patrol[]"}, -/obj/item/weapon/ed209_assembly/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/ed209_assembly/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if(istype(W, /obj/item/weapon/pen)) @@ -665,14 +663,14 @@ Auto Patrol[]"}, user << "Taser gun attached." if(9) - if(istype(W, /obj/item/weapon/cell)) + if(istype(W, /obj/item/weapon/stock_parts/cell)) build_step++ user << "You complete the ED-209." var/turf/T = get_turf(src) new /obj/machinery/bot/ed209(T,created_name,lasercolor) user.drop_item() qdel(W) - user.before_take_item(src, 1) + user.unEquip(src, 1) qdel(src) diff --git a/code/game/machinery/bots/farmbot.dm b/code/game/machinery/bots/farmbot.dm index f2981c70fe1..c8775c7f5ca 100644 --- a/code/game/machinery/bots/farmbot.dm +++ b/code/game/machinery/bots/farmbot.dm @@ -161,7 +161,7 @@ src.updateUsrDialog() return -/obj/machinery/bot/farmbot/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/bot/farmbot/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) if (src.allowed(user)) src.locked = !src.locked @@ -531,7 +531,7 @@ new /obj/structure/reagent_dispensers/watertank(src) -/obj/structure/reagent_dispensers/watertank/attackby(var/obj/item/robot_parts/S, mob/user as mob) +/obj/structure/reagent_dispensers/watertank/attackby(var/obj/item/robot_parts/S, mob/user as mob, params) if ((!istype(S, /obj/item/robot_parts/l_arm)) && (!istype(S, /obj/item/robot_parts/r_arm))) ..() @@ -544,30 +544,30 @@ A.loc = src.loc 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) + user.unEquip(S) del(S) -/obj/item/weapon/farmbot_arm_assembly/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/farmbot_arm_assembly/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if((istype(W, /obj/item/device/analyzer/plant_analyzer)) && (!src.build_step)) src.build_step++ user << "You add the plant analyzer to [src]!" src.name = "farmbot assembly" - user.u_equip(W) + user.unEquip(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) + user.unEquip(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) + user.unEquip(W) del(W) else if((isprox(W)) && (src.build_step == 3)) @@ -579,13 +579,13 @@ S.tank = wTank S.loc = get_turf(src) S.name = src.created_name - user.u_equip(W) + user.unEquip(W) del(W) del(src) else if(istype(W, /obj/item/weapon/pen)) var/t = input(user, "Enter new robot name", src.name, src.created_name) as text - t = copytext(sanitize(t), 1, MAX_NAME_LEN) + t = sanitize(copytext(t), 1, MAX_NAME_LEN) if (!t) return if (!in_range(src, usr) && src.loc != usr) diff --git a/code/game/machinery/bots/floorbot.dm b/code/game/machinery/bots/floorbot.dm index eede1892d76..a962d81d6e4 100644 --- a/code/game/machinery/bots/floorbot.dm +++ b/code/game/machinery/bots/floorbot.dm @@ -49,7 +49,6 @@ var/oldloc = null req_one_access = list(access_construction, access_robotics) var/targetdirection - radio_frequency = ENG_FREQ //Engineering channel radio_name = "Engineering" bot_type = FLOOR_BOT bot_type_name = "Floorbot" @@ -134,7 +133,7 @@ return -/obj/machinery/bot/floorbot/attackby(var/obj/item/W , mob/user as mob) +/obj/machinery/bot/floorbot/attackby(var/obj/item/W , mob/user as mob, params) if(istype(W, /obj/item/stack/tile/plasteel)) var/obj/item/stack/tile/plasteel/T = W if(amount >= 50) @@ -245,7 +244,7 @@ if(!target && replacetiles) //Finds a floor without a tile and gives it one. process_type = REPLACE_TILE //The target must be the floor and not a tile. The floor must not already have a floortile. target = scan(/turf/simulated/floor, oldtarget) - + if(!target && fixfloors) //Repairs damaged floors and tiles. process_type = FIX_TILE target = scan(/turf/simulated/floor, oldtarget) @@ -288,6 +287,8 @@ target = null mode = BOT_IDLE return + + ignore_list = list() // Reset the ignore list if(loc == target || loc == target.loc) if(istype(target, /obj/item/stack/tile/plasteel)) @@ -318,7 +319,7 @@ /obj/machinery/bot/floorbot/proc/nag() //Annoy everyone on the channel to refill us! if(!nagged) var/area/location = get_area(src) - speak("Requesting refill at [location]!", radio_frequency, radio_name) + speak("Requesting refill at [location]!", radio_name) nagged = 1 /obj/machinery/bot/floorbot/proc/is_hull_breach(var/turf/t) //Ignore space tiles not considered part of a structure, also ignores shuttle docking areas. @@ -478,7 +479,7 @@ obj/machinery/bot/floorbot/process_scan(var/scan_target) return -/obj/item/weapon/storage/toolbox/mechanical/attackby(var/obj/item/stack/tile/plasteel/T, mob/user as mob) +/obj/item/weapon/storage/toolbox/mechanical/attackby(var/obj/item/stack/tile/plasteel/T, mob/user as mob, params) if(!istype(T, /obj/item/stack/tile/plasteel)) ..() return @@ -491,13 +492,13 @@ obj/machinery/bot/floorbot/process_scan(var/scan_target) var/obj/item/weapon/toolbox_tiles/B = new /obj/item/weapon/toolbox_tiles user.put_in_hands(B) user << "You add the tiles into the empty toolbox. They protrude from the top." - user.before_take_item(src, 1) + user.unEquip(src, 1) qdel(src) else user << "You need 10 floor tiles to start building a floorbot." return -/obj/item/weapon/toolbox_tiles/attackby(var/obj/item/W, mob/user as mob) +/obj/item/weapon/toolbox_tiles/attackby(var/obj/item/W, mob/user as mob, params) ..() if(isprox(W)) qdel(W) @@ -505,7 +506,7 @@ obj/machinery/bot/floorbot/process_scan(var/scan_target) B.created_name = created_name user.put_in_hands(B) user << "You add the sensor to the toolbox and tiles!" - user.before_take_item(src, 1) + user.unEquip(src, 1) qdel(src) else if (istype(W, /obj/item/weapon/pen)) @@ -517,7 +518,7 @@ obj/machinery/bot/floorbot/process_scan(var/scan_target) created_name = t -/obj/item/weapon/toolbox_tiles_sensor/attackby(var/obj/item/W, mob/user as mob) +/obj/item/weapon/toolbox_tiles_sensor/attackby(var/obj/item/W, mob/user as mob, params) ..() if(istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm)) qdel(W) @@ -525,7 +526,7 @@ obj/machinery/bot/floorbot/process_scan(var/scan_target) var/obj/machinery/bot/floorbot/A = new /obj/machinery/bot/floorbot(T) A.name = created_name user << "You add the robot arm to the odd looking toolbox assembly! Boop beep!" - user.before_take_item(src, 1) + user.unEquip(src, 1) qdel(src) else if (istype(W, /obj/item/weapon/pen)) var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN) diff --git a/code/game/machinery/bots/medbot.dm b/code/game/machinery/bots/medbot.dm index c77a5477e13..078d9fff2b9 100644 --- a/code/game/machinery/bots/medbot.dm +++ b/code/game/machinery/bots/medbot.dm @@ -30,7 +30,6 @@ var/declare_crit = 1 //If active, the bot will transmit a critical patient alert to MedHUD users. var/declare_cooldown = 0 //Prevents spam of critical patient alerts. var/stationary_mode = 0 //If enabled, the Medibot will not move automatically. - radio_frequency = MED_FREQ //Medical frequency radio_name = "Medical" //Setting which reagents to use to treat what by default. By id. var/treatment_brute = "tricordrazine" @@ -221,7 +220,7 @@ updateUsrDialog() return -/obj/machinery/bot/medbot/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/bot/medbot/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) if (allowed(user) && !open && !emagged) locked = !locked @@ -533,7 +532,7 @@ if((skin == "bezerk")) return var/area/location = get_area(src) - speak("Medical emergency! [crit_patient ? "[crit_patient]" : "A patient"] is in critical condition at [location]!",radio_frequency, radio_name) + speak("Medical emergency! [crit_patient ? "[crit_patient]" : "A patient"] is in critical condition at [location]!", radio_name) declare_cooldown = 1 spawn(200) //Twenty seconds declare_cooldown = 0 @@ -542,7 +541,7 @@ * Medbot Assembly -- Can be made out of all three medkits. */ -/obj/item/weapon/storage/firstaid/attackby(var/obj/item/robot_parts/S, mob/user as mob) +/obj/item/weapon/storage/firstaid/attackby(var/obj/item/robot_parts/S, mob/user as mob, params) if ((!istype(S, /obj/item/robot_parts/l_arm)) && (!istype(S, /obj/item/robot_parts/r_arm))) ..() @@ -564,11 +563,11 @@ qdel(S) user.put_in_hands(A) user << "You add the robot arm to the first aid kit." - user.before_take_item(src, 1) + user.unEquip(src, 1) qdel(src) -/obj/item/weapon/firstaid_arm_assembly/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/firstaid_arm_assembly/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if(istype(W, /obj/item/weapon/pen)) var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN) @@ -598,5 +597,5 @@ var/obj/machinery/bot/medbot/S = new /obj/machinery/bot/medbot(T) S.skin = skin S.name = created_name - user.before_take_item(src, 1) + user.unEquip(src, 1) qdel(src) \ No newline at end of file diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm index bd1ee21a88c..93342641732 100644 --- a/code/game/machinery/bots/mulebot.dm +++ b/code/game/machinery/bots/mulebot.dm @@ -43,7 +43,7 @@ var/global/mulebot_count = 0 var/auto_pickup = 1 // true if auto-pickup at beacon var/report_delivery = 1 // true if bot will announce an arrival to a location. - var/obj/item/weapon/cell/cell + var/obj/item/weapon/stock_parts/cell/cell var/datum/wires/mulebot/wires = null // the installed power cell @@ -86,18 +86,13 @@ var/global/mulebot_count = 0 // screwdriver: open/close hatch // cell: insert it // other: chance to knock rider off bot -/obj/machinery/bot/mulebot/attackby(var/obj/item/I, var/mob/user) - if(istype(I,/obj/item/weapon/card/emag)) - locked = !locked - user << "You [locked ? "lock" : "unlock"] the mulebot's controls!" - flick("mulebot-emagged", src) - playsound(loc, 'sound/effects/sparks1.ogg', 100, 0) - else if(istype(I, /obj/item/weapon/card/id) || istype(I, /obj/item/device/pda)) +/obj/machinery/bot/mulebot/attackby(var/obj/item/I, var/mob/user, params) + if(istype(I, /obj/item/weapon/card/id) || istype(I, /obj/item/device/pda)) if(toggle_lock(user)) user << "Controls [(locked ? "locked" : "unlocked")]." updateUsrDialog() - else if(istype(I,/obj/item/weapon/cell) && open && !cell) - var/obj/item/weapon/cell/C = I + else if(istype(I,/obj/item/weapon/stock_parts/cell) && open && !cell) + var/obj/item/weapon/stock_parts/cell/C = I user.drop_item() C.loc = src cell = C @@ -139,7 +134,12 @@ var/global/mulebot_count = 0 ..() return - +/obj/machinery/bot/mulebot/emag_act(user as mob) + locked = !locked + user << "You [locked ? "lock" : "unlock"] the mulebot's controls!" + flick("mulebot-emagged", src) + playsound(loc, 'sound/effects/sparks1.ogg', 100, 0) + /obj/machinery/bot/mulebot/ex_act(var/severity) unload(0) switch(severity) @@ -238,7 +238,7 @@ var/global/mulebot_count = 0 //user << browse("M.U.L.E. Mk. III [suffix ? "([suffix])" : ""][dat]", "window=mulebot;size=350x500") //onclose(user, "mulebot") - var/datum/browser/popup = new(user, "mulebot", "M.U.L.E. Mk. V [suffix ? "([suffix])" : ""]", 350, 535) + var/datum/browser/popup = new(user, "mulebot", "M.U.L.E. Mk. V [suffix ? "([suffix])" : ""]", 350, 620) popup.set_content(dat) popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) popup.open() @@ -286,7 +286,7 @@ var/global/mulebot_count = 0 if("cellinsert") if(open && !cell) - var/obj/item/weapon/cell/C = usr.get_active_hand() + var/obj/item/weapon/stock_parts/cell/C = usr.get_active_hand() if(istype(C)) usr.drop_item() cell = C @@ -313,6 +313,8 @@ var/global/mulebot_count = 0 updateDialog() if("destination") + if(!delivery_beacons.len) + post_signal(beacon_freq, "findbeacon", "delivery") refresh=0 var/new_dest = input("Select M.U.L.E. Destination", "Mulebot [suffix ? "([suffix])" : ""]", destination) as null|anything in delivery_beacons refresh=1 @@ -322,7 +324,7 @@ var/global/mulebot_count = 0 if("setid") refresh=0 - var/new_id = copytext(sanitize(input("Enter new bot ID", "Mulebot [suffix ? "([suffix])" : ""]", suffix) as text|null),1,MAX_NAME_LEN) + var/new_id = sanitize(copytext(input("Enter new bot ID", "Mulebot [suffix ? "([suffix])" : ""]", suffix) as text|null,1,MAX_NAME_LEN)) refresh=1 if(new_id) suffix = new_id @@ -683,7 +685,6 @@ var/global/mulebot_count = 0 // called when bot reaches current target /obj/machinery/bot/mulebot/proc/at_target() if(!reached_target) - radio_frequency = SUP_FREQ //Supply channel radio_name = "Supply" Radio.config(list("[radio_name]" = 0)) visible_message("[src] makes a chiming sound!", "You hear a chime.") @@ -696,12 +697,11 @@ var/global/mulebot_count = 0 calling_ai << "\icon[src] [src] wirelessly plays a chiming sound!" playsound(calling_ai, 'sound/machines/chime.ogg',40, 0) calling_ai = null - radio_frequency = AIPRIV_FREQ //Report on AI Private instead if the AI is controlling us. radio_name = "AI Private" Radio.config(list("[radio_name]" = 0)) if(load) // if loaded, unload at target - speak("Destination [destination] reached. Unloading [load].", radio_frequency, radio_name) + speak("Destination [destination] reached. Unloading [load].", radio_name) unload(loaddir) else // not loaded @@ -717,7 +717,7 @@ var/global/mulebot_count = 0 if(AM) load(AM) if(report_delivery) - speak("Now loading [load] at [get_area(src)].", radio_frequency, radio_name) + speak("Now loading [load] at [get_area(src)].", radio_name) // whatever happened, check to see if we return home if(auto_return && destination != home_destination) diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm index fecf5cdcb26..a790767c851 100644 --- a/code/game/machinery/bots/secbot.dm +++ b/code/game/machinery/bots/secbot.dm @@ -25,7 +25,6 @@ var/arrest_type = 0 //If true, don't handcuff var/harmbaton = 0 var/base_icon = "secbot" - radio_frequency = SEC_FREQ //Security channel radio_name = "Security" bot_type = SEC_BOT bot_type_name = "Secbot" @@ -50,9 +49,8 @@ /obj/machinery/bot/secbot/pingsky name = "Officer Pingsky" desc = "It's Officer Pingsky! Delegated to satellite guard duty for harbouring anti-human sentiment." - radio_frequency = AIPRIV_FREQ radio_name = "AI Private" - + /obj/machinery/bot/secbot/ofitser name = "Prison Ofitser" desc = "It's Prison Ofitser! Powered by the tears and sweat of prisoners." @@ -177,7 +175,7 @@ Auto Patrol: []"}, updateUsrDialog() -/obj/machinery/bot/secbot/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/bot/secbot/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) if(allowed(user) && !open && !emagged) locked = !locked @@ -243,7 +241,7 @@ Auto Patrol: []"}, icon_state = "[base_icon][on]" var/mob/living/carbon/M = target if(istype(M, /mob/living/carbon/human)) - if( M.stuttering < 5 && !(M_HULK in M.mutations) ) + if( M.stuttering < 5 && !(HULK in M.mutations) ) M.stuttering = 5 if(harmbaton) // Bots with harmbaton enabled become shitcurity. - Dave M.apply_damage(10) @@ -256,7 +254,7 @@ Auto Patrol: []"}, if(declare_arrests) var/area/location = get_area(src) - speak("[arrest_type ? "Detaining" : "Arresting"] level [threatlevel] scumbag [target] in [location].",radio_frequency, radio_name) + speak("[arrest_type ? "Detaining" : "Arresting"] level [threatlevel] scumbag [target] in [location].", radio_name) target.visible_message("[target] has been [harmbaton ? "beaten" : "stunned"] by [src]!",\ "[target] has been [harmbaton ? "beaten" : "stunned"] by [src]!") @@ -286,15 +284,15 @@ Auto Patrol: []"}, if(!arrest_type) if(!target.handcuffed) //he's not cuffed? Try to cuff him! mode = BOT_ARREST - playsound(loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2) - target.visible_message("[src] is trying to put handcuffs on [target]!",\ - "[src] is trying to put handcuffs on [target]!") - spawn(60) + playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) + target.visible_message("[src] is trying to put zipties on [target]!",\ + "[src] is trying to put zipties on [target]!") + spawn(30) if( !Adjacent(target) || !isturf(target.loc) ) //if he's in a closet or not adjacent, we cancel cuffing. return if(!target.handcuffed) - target.handcuffed = new /obj/item/weapon/handcuffs(target) - target.update_inv_handcuffed(0) //update the handcuffs overlay + target.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(target) + target.update_inv_handcuffed(1) //update the handcuffs overlay playsound(loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0) back_to_idle() else @@ -414,7 +412,7 @@ Auto Patrol: []"}, //Secbot Construction -/obj/item/clothing/head/helmet/attackby(var/obj/item/device/assembly/signaler/S, mob/user as mob) +/obj/item/clothing/head/helmet/attackby(var/obj/item/device/assembly/signaler/S, mob/user as mob, params) ..() if(!issignaler(S)) ..() @@ -428,12 +426,12 @@ Auto Patrol: []"}, var/obj/item/weapon/secbot_assembly/A = new /obj/item/weapon/secbot_assembly user.put_in_hands(A) user << "You add the signaler to the helmet." - user.before_take_item(src, 1) + user.unEquip(src, 1) qdel(src) else return -/obj/item/weapon/secbot_assembly/attackby(obj/item/I, mob/user) +/obj/item/weapon/secbot_assembly/attackby(obj/item/I, mob/user, params) ..() if(istype(I, /obj/item/weapon/weldingtool)) if(!build_step) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 977c1bd3d3e..e60921e700b 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -14,11 +14,10 @@ var/c_tag_order = 999 var/status = 1.0 anchored = 1.0 + var/start_active = 0 //If it ignores the random chance to start broken on round start var/invuln = null - var/bugged = 0 + var/obj/item/device/camera_bug/bug = null var/obj/item/weapon/camera_assembly/assembly = null - var/watcherslist = list() - var/obj/item/device/camera_bug/hasbug = null //OTHER @@ -28,26 +27,40 @@ var/light_disabled = 0 var/alarm_on = 0 var/busy = 0 - var/indestructible = 0 // If set, prevents aliens from destroying it + var/emped = 0 //Number of consecutive EMP's on this camera /obj/machinery/camera/New() wires = new(src) assembly = new(src) assembly.state = 4 + assembly.anchored = 1 + assembly.update_icon() + /* // Use this to look for cameras that have the same c_tag. - for(var/obj/machinery/camera/C in cameranet.viewpoints) + for(var/obj/machinery/camera/C in cameranet.cameras) var/list/tempnetwork = C.network&src.network if(C != src && C.c_tag == src.c_tag && tempnetwork.len) world.log << "[src.c_tag] [src.x] [src.y] [src.z] conflicts with [C.c_tag] [C.x] [C.y] [C.z]" */ - if(!src.network || src.network.len < 1) - if(loc) - error("[src.name] in [get_area(src)] (x:[src.x] y:[src.y] z:[src.z] has errored. [src.network?"Empty network list":"Null network list"]") - else - error("[src.name] in [get_area(src)]has errored. [src.network?"Empty network list":"Null network list"]") - ASSERT(src.network) - ASSERT(src.network.len > 0) + ..() + +/obj/machinery/camera/initialize() + if(z == 1 && prob(3) && !start_active) + deactivate() + +/obj/machinery/camera/Destroy() + deactivate(null, 0) //kick anyone viewing out + if(assembly) + qdel(assembly) + assembly = null + if(istype(bug)) + bug.bugged_cameras -= src.c_tag + if(bug.current == src) + bug.current = null + bug = null + del(wires) + cameranet.removeCamera(src) //Will handle removal from the camera network and the chunks, so we don't need to worry about that ..() /obj/machinery/camera/emp_act(severity) @@ -60,30 +73,35 @@ stat |= EMPED SetLuminosity(0) triggerCameraAlarm() + emped = emped+1 //Increase the number of consecutive EMP's + var/thisemp = emped //Take note of which EMP this proc is for spawn(900) - network = previous_network - icon_state = initial(icon_state) - stat &= ~EMPED - cancelCameraAlarm() - if(can_use()) - cameranet.addCamera(src) + if(loc) //qdel limbo + if(emped == thisemp) //Only fix it if the camera hasn't been EMP'd again + network = previous_network + icon_state = initial(icon_state) + stat &= ~EMPED + cancelCameraAlarm() + if(can_use()) + cameranet.addCamera(src) + emped = 0 //Resets the consecutive EMP count for(var/mob/O in mob_list) - if(O.client && O.client.eye == src) + if (O.client && O.client.eye == src) O.unset_machine() O.reset_view(null) O << "The screen bursts into static." ..() -/obj/machinery/camera/ex_act(severity) +/obj/machinery/camera/ex_act(severity, target) if(src.invuln) return else - ..(severity) + ..() return /obj/machinery/camera/blob_act() - del(src) + qdel(src) return /obj/machinery/camera/proc/setViewRange(var/num = 7) @@ -98,8 +116,7 @@ /obj/machinery/camera/attack_paw(mob/living/carbon/alien/humanoid/user as mob) if(!istype(user)) return - if(indestructible) - return + user.do_attack_animation(src) status = 0 visible_message("\The [user] slashes at [src]!") playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1) @@ -107,7 +124,9 @@ add_hiddenprint(user) deactivate(user,0) -/obj/machinery/camera/attackby(W as obj, mob/living/user as mob) +/obj/machinery/camera/attackby(W as obj, mob/living/user as mob, params) + var/msg = "You attach [W] into the assembly inner circuits." + var/msg2 = "The camera already has that upgrade!" // DECONSTRUCTION if(istype(W, /obj/item/weapon/screwdriver)) @@ -123,11 +142,38 @@ else if(istype(W, /obj/item/weapon/weldingtool) && wires.CanDeconstruct()) if(weld(W, user)) - if(assembly) - assembly.loc = src.loc - assembly.state = 1 - del(src) + user << "You unweld the camera leaving it as just a frame screwed to the wall." + if(!assembly) + assembly = new() + assembly.loc = src.loc + assembly.state = 1 + assembly.dir = src.dir + assembly.update_icon() + assembly = null + qdel(src) + return + else if(istype(W, /obj/item/device/analyzer) && panel_open) //XRay + if(!isXRay()) + upgradeXRay() + qdel(W) + user << "[msg]" + else + user << "[msg2]" + else if(istype(W, /obj/item/stack/sheet/mineral/plasma) && panel_open) + if(!isEmpProof()) + upgradeEmpProof() + user << "[msg]" + qdel(W) + else + user << "[msg2]" + else if(istype(W, /obj/item/device/assembly/prox_sensor) && panel_open) + if(!isMotion()) + upgradeMotion() + user << "[msg]" + qdel(W) + else + user << "[msg2]" // OTHER else if ((istype(W, /obj/item/weapon/paper) || istype(W, /obj/item/device/pda)) && isliving(user)) @@ -145,37 +191,29 @@ P = W itemname = P.name info = P.notehtml - U << "You hold \a [itemname] up to the camera ..." - for(var/mob/living/silicon/ai/O in living_mob_list) - if(!O.client) continue - if(U.name == "Unknown") O << "[U] holds \a [itemname] up to one of your cameras ..." - else O << "[U] holds \a [itemname] up to one of your cameras ..." - O << browse(text("[][]", itemname, info), text("window=[]", itemname)) + U << "You hold \the [itemname] up to the camera ..." + U.changeNext_move(CLICK_CD_MELEE) for(var/mob/O in player_list) - if(O.client && O.client.eye == src) - O.unset_machine() - O.reset_view(null) - O << "[U] holds \a [itemname] up to the camera..." - O << browse("[itemname][info]","window=[itemname]") - else if (istype(W, /obj/item/device/camera_bug) && panel_open) + if(istype(O, /mob/living/silicon/ai)) + var/mob/living/silicon/ai/AI = O + if(U.name == "Unknown") AI << "[U] holds \a [itemname] up to one of your cameras ..." + else AI << "[U] holds \a [itemname] up to one of your cameras ..." + AI.last_paper_seen = "[itemname][info]" + else if (O.client && O.client.eye == src) + O << "[U] holds \a [itemname] up to one of the cameras ..." + O << browse(text("[][]", itemname, info), text("window=[]", itemname)) + else if (istype(W, /obj/item/device/camera_bug)) if (!src.can_use()) - user << "\blue Camera non-functional" + user << "Camera non-functional." return + if(istype(src.bug)) + user << "Camera bug removed." + src.bug.bugged_cameras -= src.c_tag + src.bug = null else - user << "\blue Camera bugged." - user.drop_item(W) - hasbug = W - contents += W - if(prob(15)) - spawn(30) - if(src.can_use() && hasbug) - desc += "
The power light on the camera is blinking" - triggerCameraAlarm() - else if (iscrowbar(W) && panel_open && src.hasbug) - user << "\blue You retrieve \the [hasbug]" - user.put_in_hands(hasbug) - hasbug = null - deactivatebug(user) + user << "Camera bugged." + src.bug = W + src.bug.bugged_cameras[src.c_tag] = src else if(istype(W, /obj/item/weapon/melee/energy/blade))//Putting it here last since it's a special case. I wonder if there is a better way to do these than type casting. deactivate(user,2)//Here so that you can disconnect anyone viewing the camera, regardless if it's on or off. var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() @@ -183,49 +221,41 @@ spark_system.start() playsound(loc, 'sound/weapons/blade1.ogg', 50, 1) playsound(loc, "sparks", 50, 1) - visible_message("\blue The camera has been sliced apart by [] with an energy blade!") - del(src) + visible_message("[user] has sliced the camera apart with an energy blade!") + qdel(src) else if(istype(W, /obj/item/device/laser_pointer)) var/obj/item/device/laser_pointer/L = W L.laser_act(src, user) else ..() return -/obj/machinery/camera/proc/deactivatebug(user as mob) - for(var/mob/O in player_list) - if(istype(O.machine, /obj/item/device/handtv)) - var/obj/item/device/handtv/S = O.machine - if (S.current == src) - O.unset_machine() - O.reset_view(null) - O << "The screen bursts into static." /obj/machinery/camera/proc/deactivate(user as mob, var/choice = 1) if(choice==1) status = !( src.status ) if (!(src.status)) if(user) - visible_message("\red [user] has deactivated [src]!") + visible_message("[user] deactivates [src]!") add_hiddenprint(user) else - visible_message("\red \The [src] deactivates!") + visible_message("\The [src] deactivates!") playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1) icon_state = "[initial(icon_state)]1" - add_hiddenprint(user) + else if(user) - visible_message("\red [user] has reactivated [src]!") + visible_message("[user] reactivates [src]!") add_hiddenprint(user) else - visible_message("\red \the [src] reactivates!") + visible_message("\The [src] reactivates!") playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1) icon_state = initial(icon_state) - add_hiddenprint(user) + // now disconnect anyone using the camera //Apparently, this will disconnect anyone even if the camera was re-activated. //I guess that doesn't matter since they can't use it anyway? for(var/mob/O in player_list) - if(O.client && O.client.eye == src) + if (O.client && O.client.eye == src) O.unset_machine() O.reset_view(null) O << "The screen bursts into static." @@ -239,7 +269,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) @@ -301,7 +331,7 @@ return 0 // Do after stuff here - user << "You start to weld the [src].." + user << "You start to weld [src]." playsound(src.loc, 'sound/items/Welder.ogg', 50, 1) WT.eyecheck(user) busy = 1 diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index 9f6eb2210af..f91565511f5 100644 --- a/code/game/machinery/camera/camera_assembly.dm +++ b/code/game/machinery/camera/camera_assembly.dm @@ -1,16 +1,15 @@ /obj/item/weapon/camera_assembly name = "camera assembly" - desc = "The basic construction for Nanotrasen-Always-Watching-You cameras." + desc = "A pre-fabricated security camera kit, ready to be assembled and mounted to a surface." icon = 'icons/obj/monitors.dmi' icon_state = "cameracase" w_class = 2 anchored = 0 - - m_amt = 700 - g_amt = 300 + m_amt = 400 + g_amt = 250 // Motion, EMP-Proof, X-Ray - var/list/obj/item/possible_upgrades = list(/obj/item/device/assembly/prox_sensor, /obj/item/stack/sheet/mineral/plasma, /obj/item/weapon/reagent_containers/food/snacks/grown/carrot) + var/list/obj/item/possible_upgrades = list(/obj/item/device/assembly/prox_sensor, /obj/item/stack/sheet/mineral/plasma, /obj/item/device/analyzer) var/list/upgrades = list() var/state = 0 var/busy = 0 @@ -22,7 +21,7 @@ 4 = Screwdriver panel closed and is fully built (you cannot attach upgrades) */ -/obj/item/weapon/camera_assembly/attackby(obj/item/W as obj, mob/living/user as mob) +/obj/item/weapon/camera_assembly/attackby(obj/item/W as obj, mob/living/user as mob, params) switch(state) @@ -59,8 +58,10 @@ if(iscoil(W)) var/obj/item/stack/cable_coil/C = W if(C.use(2)) - user << "You add wires to the assembly." + user << "You add wires to the assembly." state = 3 + else + user << "You need 2 coils of wire to wire the assembly." return else if(iswelder(W)) @@ -87,7 +88,8 @@ usr << "No network found please hang up and try your call again." return - var/temptag = "[get_area(src)] ([rand(1, 999)])" + var/area/camera_area = get_area(src) + var/temptag = "[sanitize(camera_area.name)] ([rand(1, 999)])" input = strip_html(input(usr, "How would you like to name the camera?", "Set Camera Name", temptag)) state = 4 @@ -98,7 +100,7 @@ C.auto_turn() C.network = uniquelist(tempnetwork) - tempnetwork = difflist(C.network,RESTRICTED_CAMERA_NETWORKS) + tempnetwork = difflist(C.network,restricted_camera_networks) if(!tempnetwork.len)//Camera isn't on any open network - remove its chunk from AI visibility. cameranet.removeCamera(C) @@ -124,7 +126,7 @@ // Upgrades! if(is_type_in_list(W, possible_upgrades) && !is_type_in_list(W, upgrades)) // Is a possible upgrade and isn't in the camera already. - user << "You attach the [W] into the assembly inner circuits." + user << "You attach \the [W] into the assembly inner circuits." upgrades += W user.drop_item(W) W.loc = src @@ -169,4 +171,4 @@ return 0 return 1 busy = 0 - return 0 \ No newline at end of file + return 0 diff --git a/code/game/machinery/camera/motion.dm b/code/game/machinery/camera/motion.dm index 588ab5005ce..0c6f7d95a7f 100644 --- a/code/game/machinery/camera/motion.dm +++ b/code/game/machinery/camera/motion.dm @@ -8,6 +8,8 @@ /obj/machinery/camera/process() // motion camera event loop + if (stat & (EMPED|NOPOWER)) + return if(!isMotion()) . = PROCESS_KILL return @@ -40,16 +42,20 @@ cancelAlarm() /obj/machinery/camera/proc/cancelAlarm() + if (!status || (stat & NOPOWER)) + return 0 if (detectTime == -1) for (var/mob/living/silicon/aiPlayer in player_list) - if (status) aiPlayer.cancelAlarm("Motion", src.loc.loc) + aiPlayer.cancelAlarm("Motion", get_area(src), src) detectTime = 0 return 1 /obj/machinery/camera/proc/triggerAlarm() + if (!status || (stat & NOPOWER)) + return 0 if (!detectTime) return 0 for (var/mob/living/silicon/aiPlayer in player_list) - if (status) aiPlayer.triggerAlarm("Motion", src.loc.loc, src) + aiPlayer.triggerAlarm("Motion", get_area(src), list(src), src) detectTime = -1 return 1 diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm index 0ee0e622b8b..84ec6734e1b 100644 --- a/code/game/machinery/camera/presets.dm +++ b/code/game/machinery/camera/presets.dm @@ -57,7 +57,7 @@ return O /obj/machinery/camera/proc/isXRay() - var/O = locate(/obj/item/weapon/reagent_containers/food/snacks/grown/carrot) in assembly.upgrades + var/O = locate(/obj/item/device/analyzer) in assembly.upgrades return O /obj/machinery/camera/proc/isMotion() @@ -68,10 +68,21 @@ /obj/machinery/camera/proc/upgradeEmpProof() assembly.upgrades.Add(new /obj/item/stack/sheet/mineral/plasma(assembly)) + setPowerUsage() /obj/machinery/camera/proc/upgradeXRay() - assembly.upgrades.Add(new /obj/item/weapon/reagent_containers/food/snacks/grown/carrot(assembly)) + assembly.upgrades.Add(new /obj/item/device/analyzer(assembly)) + setPowerUsage() // If you are upgrading Motion, and it isn't in the camera's New(), add it to the machines list. /obj/machinery/camera/proc/upgradeMotion() - assembly.upgrades.Add(new /obj/item/device/assembly/prox_sensor(assembly)) \ No newline at end of file + assembly.upgrades.Add(new /obj/item/device/assembly/prox_sensor(assembly)) + setPowerUsage() + +/obj/machinery/camera/proc/setPowerUsage() + var/mult = 1 + if (isXRay()) + mult++ + if (isMotion()) + mult++ + active_power_usage = mult*initial(active_power_usage) diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm index 47b2edf9fac..dd7c175ce4d 100644 --- a/code/game/machinery/camera/tracking.dm +++ b/code/game/machinery/camera/tracking.dm @@ -1,16 +1,25 @@ +/mob/living/silicon/ai/var/max_locations = 10 +/mob/living/silicon/ai/var/stored_locations[0] + +/mob/living/silicon/ai/proc/InvalidTurf(turf/T as turf) + if(!T) + return 1 + if((T.z in config.admin_levels)) + return 1 + if(T.z > 6) + return 1 + return 0 + /mob/living/silicon/ai/proc/get_camera_list() + if(src.stat == 2) return - var/list/L = list() - for (var/obj/machinery/camera/C in cameranet.viewpoints) - L.Add(C) - - camera_sort(L) + cameranet.process_sort() var/list/T = list() T["Cancel"] = "Cancel" - for (var/obj/machinery/camera/C in L) + for (var/obj/machinery/camera/C in cameranet.cameras) var/list/tempnetwork = C.network&src.network if (tempnetwork.len) T[text("[][]", C.c_tag, (C.can_use() ? null : " (Deactivated)"))] = C @@ -19,20 +28,76 @@ track.cameras = T return T + /mob/living/silicon/ai/proc/ai_camera_list(var/camera in get_camera_list()) + set category = "AI Commands" + set name = "Show Camera List" + if(src.stat == 2) src << "You can't list the cameras because you are dead!" return if (!camera || camera == "Cancel") return 0 - + var/obj/machinery/camera/C = track.cameras[camera] - track = null src.eyeobj.setLoc(C) return +/mob/living/silicon/ai/proc/ai_store_location(loc as text) + set category = "AI Commands" + set name = "Store Camera Location" + set desc = "Stores your current camera location by the given name" + + loc = sanitize(copytext(loc, 1, MAX_MESSAGE_LEN)) + if(!loc) + src << "\red Must supply a location name" + return + + if(stored_locations.len >= max_locations) + src << "\red Cannot store additional locations. Remove one first" + return + + if(loc in stored_locations) + src << "\red There is already a stored location by this name" + return + + var/L = src.eyeobj.getLoc() + if (InvalidTurf(get_turf(L))) + src << "\red Unable to store this location" + return + + stored_locations[loc] = L + src << "Location '[loc]' stored" + +/mob/living/silicon/ai/proc/sorted_stored_locations() + return sortList(stored_locations) + +/mob/living/silicon/ai/proc/ai_goto_location(loc in sorted_stored_locations()) + set category = "AI Commands" + set name = "Goto Camera Location" + set desc = "Returns to the selected camera location" + + if (!(loc in stored_locations)) + src << "\red Location [loc] not found" + return + + var/L = stored_locations[loc] + src.eyeobj.setLoc(L) + +/mob/living/silicon/ai/proc/ai_remove_location(loc in sorted_stored_locations()) + set category = "AI Commands" + set name = "Delete Camera Location" + set desc = "Deletes the selected camera location" + + if (!(loc in stored_locations)) + src << "\red Location [loc] not found" + return + + stored_locations.Remove(loc) + src << "Location [loc] removed" + // Used to allow the AI is write in mob names/camera name from the CMD line. /datum/trackable var/list/names = list() @@ -50,12 +115,7 @@ for(var/mob/living/M in mob_list) // Easy checks first. // Don't detect mobs on Centcom. Since the wizard den is on Centcomm, we only need this. - var/turf/T = get_turf(M) - if(!T) - continue - if(T.z == 2) - continue - if(T.z > 6) + if(InvalidTurf(get_turf(M))) continue if(M == usr) continue @@ -72,11 +132,8 @@ //Cameras can't track people wearing an agent card or a ninja hood. if(H.wear_id && istype(H.wear_id.GetID(), /obj/item/weapon/card/id/syndicate)) continue - if(istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja)) - var/obj/item/clothing/head/helmet/space/space_ninja/hood = H.head - if(!hood.canremove) - continue - + if(istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja) && (H.head.flags & NODROP)) + continue // Now, are they viewable by a camera? (This is last because it's the most intensive check) if(!near_camera(M)) continue @@ -98,6 +155,10 @@ return targets /mob/living/silicon/ai/proc/ai_camera_track(var/target_name in trackable_mobs()) + set category = "AI Commands" + set name = "Track With Camera" + set desc = "Select who you would like to track." + if(src.stat == 2) src << "You can't track with camera because you are dead!" return @@ -108,61 +169,18 @@ src.track = null ai_actual_track(target) -/mob/living/silicon/ai/proc/open_nearest_door(mob/living/target as mob) - if(!istype(target)) return - spawn(0) - if(istype(target, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = target - if(H.wear_id && istype(H.wear_id.GetID(), /obj/item/weapon/card/id/syndicate)) - src << "Unable to locate an airlock" - return - if(H.wear_id && istype(H.wear_id.GetID(), /obj/item/weapon/card/id/syndicate)) - src << "Unable to locate an airlock" - return - if(istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja) && !H.head.canremove) - src << "Unable to locate an airlock" - return - if(H.digitalcamo) - src << "Unable to locate an airlock" - return - if (!near_camera(target)) - src << "Target is not near any active cameras." - return - var/obj/machinery/door/airlock/tobeopened - var/dist = -1 - for(var/obj/machinery/door/airlock/D in range(3,target)) - if(!D.density) continue - if(dist < 0) - dist = get_dist(D, target) - //world << dist - tobeopened = D - else - if(dist > get_dist(D, target)) - dist = get_dist(D, target) - //world << dist - tobeopened = D - //world << "found [tobeopened.name] closer" - else - //world << "[D.name] not close enough | [get_dist(D, target)] | [dist]" - if(tobeopened) - switch(alert(src, "Do you want to open \the [tobeopened] for [target]?","Doorknob_v2a.exe","Yes","No")) - if("Yes") - var/nhref = "src=\ref[tobeopened];aiEnable=7" - tobeopened.Topic(nhref, params2list(nhref), tobeopened, 1) - src << "\blue You've opened \the [tobeopened] for [target]." - if("No") - src << "\red You deny the request." - else - src << "\red You've failed to open an airlock for [target]" +/mob/living/silicon/ai/proc/ai_cancel_tracking(var/forced = 0) + if(!cameraFollow) return -/mob/living/silicon/ai/proc/ai_actual_track(atom/target as mob|obj) + + src << "Follow camera mode [forced ? "terminated" : "ended"]." + cameraFollow = null + +/mob/living/silicon/ai/proc/ai_actual_track(atom/movable/target as mob|obj) if(!istype(target)) return var/mob/living/silicon/ai/U = usr U.cameraFollow = target - //U << text("Now tracking [] on camera.", target.name) - //if (U.machine == null) - // U.machine = U U << "Now tracking [target.name] on camera." spawn (0) @@ -172,30 +190,26 @@ if (istype(target, /mob/living/carbon/human)) var/mob/living/carbon/human/H = target if(H.wear_id && istype(H.wear_id.GetID(), /obj/item/weapon/card/id/syndicate)) - U << "Follow camera mode terminated." - U.cameraFollow = null + U.ai_cancel_tracking(1) return -/* if(istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja) && !H.head.canremove) - U << "Follow camera mode terminated." - U.cameraFollow = null - return*/ if(H.digitalcamo) - U << "Follow camera mode terminated." - U.cameraFollow = null + U.ai_cancel_tracking(1) + return + if(H.head && istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja) && (H.head.flags & NODROP)) + U.ai_cancel_tracking(1) return if(istype(target.loc,/obj/effect/dummy)) - U << "Follow camera mode ended." - U.cameraFollow = null + U.ai_cancel_tracking() return - if (!near_camera(target)) + if (!trackable(target)) U << "Target is not near any active cameras." sleep(100) continue if(U.eyeobj) - U.eyeobj.setLoc(get_turf(target)) + U.eyeobj.setLoc(get_turf(target), 0) else view_core() return @@ -212,6 +226,12 @@ return 0 return 1 +/proc/trackable(atom/movable/M) + var/turf/T = get_turf(M) + if(T && (T.z in config.contact_levels)) + return 1 + + return near_camera(M) /obj/machinery/camera/attack_ai(var/mob/living/silicon/ai/user as mob) if (!istype(user)) @@ -223,19 +243,3 @@ /mob/living/silicon/ai/attack_ai(var/mob/user as mob) ai_camera_list() - -/proc/camera_sort(list/L) - var/obj/machinery/camera/a - var/obj/machinery/camera/b - - for (var/i = L.len, i > 0, i--) - for (var/j = 1 to i - 1) - a = L[j] - b = L[j + 1] - if (a.c_tag_order != b.c_tag_order) - if (a.c_tag_order > b.c_tag_order) - L.Swap(j, j + 1) - else - if (sorttext(a.c_tag, b.c_tag) < 0) - L.Swap(j, j + 1) - return L diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm index 16c39585dfa..823671c2019 100644 --- a/code/game/machinery/cell_charger.dm +++ b/code/game/machinery/cell_charger.dm @@ -8,7 +8,7 @@ idle_power_usage = 5 active_power_usage = 60 power_channel = EQUIP - var/obj/item/weapon/cell/charging = null + var/obj/item/weapon/stock_parts/cell/charging = null var/chargelevel = -1 proc updateicon() @@ -34,11 +34,11 @@ if(charging) usr << "Current charge: [charging.charge]" - attackby(obj/item/weapon/W, mob/user) + attackby(obj/item/weapon/W, mob/user, params) if(stat & BROKEN) return - if(istype(W, /obj/item/weapon/cell) && anchored) + if(istype(W, /obj/item/weapon/stock_parts/cell) && anchored) if(charging) user << "\red There is already a cell in the charger." return diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index f7eb7803fd4..27e16c1be95 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -328,7 +328,7 @@ return //Let's unlock this early I guess. Might be too early, needs tweaking. -/obj/machinery/clonepod/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/clonepod/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/screwdriver)) if(occupant || mess || locked) user << "The maintenance panel is locked." diff --git a/code/game/machinery/computer/HolodeckControl.dm b/code/game/machinery/computer/HolodeckControl.dm index cd78210b41f..a14da59c097 100644 --- a/code/game/machinery/computer/HolodeckControl.dm +++ b/code/game/machinery/computer/HolodeckControl.dm @@ -161,45 +161,17 @@ -/obj/machinery/computer/HolodeckControl/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob) -//Warning, uncommenting this can have concequences. For example, deconstructing the computer may cause holographic eswords to never derez - -/* if(istype(D, /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/comm_traffic/M = new /obj/item/weapon/circuitboard/comm_traffic( 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/comm_traffic/M = new /obj/item/weapon/circuitboard/comm_traffic( 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(D, /obj/item/weapon/card/emag) && !emagged) +/obj/machinery/computer/HolodeckControl/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob, params) + return + +/obj/machinery/computer/HolodeckControl/emag_act(user as mob) + if(!emagged) playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) emagged = 1 user << "\blue You vastly increase projector power and override the safety and security protocols." user << "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call Nanotrasen maintenance and do not use the simulator." log_game("[key_name(usr)] emagged the Holodeck Control Computer") - src.updateUsrDialog() - return + src.updateUsrDialog() /obj/machinery/computer/HolodeckControl/New() ..() @@ -269,8 +241,7 @@ if(isobj(obj)) var/mob/M = obj.loc if(ismob(M)) - M.u_equip(obj) - M.update_icons() //so their overlays update + M.unEquip(obj, 1) //Holoweapons should always drop. if(!silent) var/obj/oldobj = obj @@ -394,7 +365,7 @@ var/turf/simulated/floor/FF = get_step(src,direction) FF.update_icon() //so siding get updated properly -/turf/simulated/floor/holofloor/attackby(obj/item/weapon/W as obj, mob/user as mob) +/turf/simulated/floor/holofloor/attackby(obj/item/weapon/W as obj, mob/user as mob, params) return // HOLOFLOOR DOES NOT GIVE A FUCK @@ -431,7 +402,7 @@ return // HOLOTABLE DOES NOT GIVE A FUCK -/obj/structure/table/holotable/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/table/holotable/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2) var/obj/item/weapon/grab/G = W if(G.state<2) @@ -489,7 +460,7 @@ throw_range = 5 throwforce = 0 w_class = 2.0 - flags = FPRINT | TABLEPASS | NOSHIELD + flags = NOSHIELD var/active = 0 /obj/item/weapon/holo/esword/green @@ -551,7 +522,7 @@ density = 1 throwpass = 1 -/obj/structure/holohoop/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/holohoop/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2) var/obj/item/weapon/grab/G = W if(G.state<2) @@ -609,7 +580,7 @@ ..() -/obj/machinery/readybutton/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/readybutton/attackby(obj/item/weapon/W as obj, mob/user as mob, params) user << "The device is a solid button, there's nothing you can do with it!" /obj/machinery/readybutton/attack_hand(mob/user as mob) diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm index bfd979025be..9f73b206443 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/Operating.dm @@ -73,7 +73,7 @@ /obj/machinery/computer/operating/Topic(href, href_list) if(..()) - return + return 1 if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) usr.set_machine(src) return diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm index 99751ab3296..d408d934c25 100644 --- a/code/game/machinery/computer/ai_core.dm +++ b/code/game/machinery/computer/ai_core.dm @@ -10,7 +10,7 @@ var/obj/item/device/mmi/brain = null -/obj/structure/AIcore/attackby(obj/item/P as obj, mob/user as mob) +/obj/structure/AIcore/attackby(obj/item/P as obj, mob/user as mob, params) switch(state) if(0) if(istype(P, /obj/item/weapon/wrench)) @@ -174,8 +174,12 @@ icon_state = "ai-empty" anchored = 1 state = 20//So it doesn't interact based on the above. Not really necessary. + +/obj/structure/AIcore/deactivated/Destroy() + empty_playable_ai_cores -= src + ..() -/obj/structure/AIcore/deactivated/attackby(var/obj/item/W, var/mob/user) +/obj/structure/AIcore/deactivated/attackby(var/obj/item/W, var/mob/user, params) if(istype(W, /obj/item/device/aicard))//Is it? var/obj/item/device/aicard/card = W card.transfer_ai("INACTIVE","AICARD",src,user) diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm index 7a45f1a8114..51c8626c1d1 100644 --- a/code/game/machinery/computer/aifixer.dm +++ b/code/game/machinery/computer/aifixer.dm @@ -13,7 +13,7 @@ src.overlays += image('icons/obj/computer.dmi', "ai-fixer-empty") -/obj/machinery/computer/aifixer/attackby(I as obj, user as mob) +/obj/machinery/computer/aifixer/attackby(I as obj, user as mob, params) if(istype(I, /obj/item/device/aicard)) if(stat & (NOPOWER|BROKEN)) user << "This terminal isn't functioning right now, get it working!" @@ -79,7 +79,7 @@ /obj/machinery/computer/aifixer/Topic(href, href_list) if(..()) - return + return 1 if (href_list["fix"]) src.active = 1 src.overlays += image('icons/obj/computer.dmi', "ai-fixer-on") diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index a3402129d88..7831bfc8f87 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -31,6 +31,8 @@ /obj/item/toy/carpplushie = 2, /obj/item/toy/minimeteor = 2, /obj/item/toy/redbutton = 2, + /obj/item/toy/owl = 2, + /obj/item/toy/griffin = 2, /obj/item/clothing/head/blob = 2, /obj/item/weapon/id_decal/gold = 2, /obj/item/weapon/id_decal/silver = 2, @@ -144,7 +146,10 @@ /obj/machinery/computer/arcade/battle/Topic(href, href_list) if(..()) - return + return 1 + + if(usr.machine != src) + return 0 if (!src.blocked && !src.gameover) if (href_list["attack"]) @@ -269,8 +274,8 @@ return -/obj/machinery/computer/arcade/battle/attackby(I as obj, user as mob) - if(istype(I, /obj/item/weapon/card/emag) && !emagged) +/obj/machinery/computer/arcade/battle/emag_act(user as mob) + if(!emagged) temp = "If you die in the game, you die for real!" player_hp = 30 player_mp = 10 @@ -284,14 +289,7 @@ enemy_name = "Cuban Pete" name = "Outbomb Cuban Pete" - src.updateUsrDialog() - else - - ..() - - - /obj/machinery/computer/arcade/orion_trail name = "The Orion Trail" @@ -405,7 +403,9 @@ /obj/machinery/computer/arcade/orion_trail/Topic(href, href_list) if(..()) - return + return 1 + if(usr.machine != src) + return 0 if(href_list["close"]) usr.unset_machine() usr << browse(null, "window=arcade") @@ -566,4 +566,5 @@ /obj/machinery/computer/arcade/orion_trail/proc/win() playing = 0 + turns = 0 prizevend() diff --git a/code/game/machinery/computer/atmos_alert.dm b/code/game/machinery/computer/atmos_alert.dm index 9a0ff286700..5e9bb34866b 100644 --- a/code/game/machinery/computer/atmos_alert.dm +++ b/code/game/machinery/computer/atmos_alert.dm @@ -23,8 +23,10 @@ var/zone = signal.data["zone"] var/severity = signal.data["alert"] + var/hidden = signal.data["hidden"] if(!zone || !severity) return + if(hidden) return minor_alarms -= zone priority_alarms -= zone @@ -98,7 +100,7 @@ /obj/machinery/computer/atmos_alert/Topic(href, href_list) if(..()) - return + return 1 if(href_list["priority_clear"]) var/removing_zone = href_list["priority_clear"] diff --git a/code/game/machinery/computer/atmos_control.dm b/code/game/machinery/computer/atmos_control.dm index df9a3cbef9e..bce0006f488 100644 --- a/code/game/machinery/computer/atmos_control.dm +++ b/code/game/machinery/computer/atmos_control.dm @@ -37,15 +37,16 @@ return ui_interact(user) -/obj/machinery/computer/atmoscontrol/attackby(var/obj/item/I as obj, var/mob/user as mob) - if(istype(I, /obj/item/weapon/card/emag) && !emagged) - user.visible_message("\red \The [user] swipes \a [I] through \the [src], causing the screen to flash!",\ - "\red You swipe your [I] through \the [src], the screen flashing as you gain full control.",\ +/obj/machinery/computer/atmoscontrol/emag_act(user as mob) + if(!emagged) + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user + H.visible_message("\red \The [user] swipes \a card through \the [src], causing the screen to flash!",\ + "\red You swipe your card through \the [src], the screen flashing as you gain full control.",\ "You hear the swipe of a card through a reader, and an electronic warble.") emagged = 1 overridden = 1 - return - return ..() /obj/machinery/computer/atmoscontrol/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null) if(user.stat && !isobserver(user)) @@ -115,7 +116,7 @@ //a bunch of this is copied from atmos alarms /obj/machinery/computer/atmoscontrol/Topic(href, href_list) if(..()) - return + return 1 if(href_list["reset"]) current = null diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index eb8efc36264..23743ffc10c 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -233,7 +233,7 @@ board_type = "honkcomputer" -/obj/item/weapon/circuitboard/supplycomp/attackby(obj/item/I as obj, mob/user as mob) +/obj/item/weapon/circuitboard/supplycomp/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I,/obj/item/device/multitool)) var/catastasis = src.contraband_enabled var/opposite_catastasis @@ -255,7 +255,7 @@ user << "DERP! BUG! Report this (And what you were doing to cause it) to Agouri" return -/obj/item/weapon/circuitboard/rdconsole/attackby(obj/item/I as obj, mob/user as mob) +/obj/item/weapon/circuitboard/rdconsole/attackby(obj/item/I as obj, mob/user as mob, params) 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") @@ -268,7 +268,7 @@ user << "\blue Access protocols set to default." return -/obj/structure/computerframe/attackby(obj/item/P as obj, mob/user as mob) +/obj/structure/computerframe/attackby(obj/item/P as obj, mob/user as mob, params) switch(state) if(0) if(istype(P, /obj/item/weapon/wrench)) @@ -379,7 +379,7 @@ name = "Bananium Computer-frame" icon = 'icons/obj/machines/HONKputer.dmi' -/obj/structure/computerframe/HONKputer/attackby(obj/item/P as obj, mob/user as mob) +/obj/structure/computerframe/HONKputer/attackby(obj/item/P as obj, mob/user as mob, params) switch(state) if(0) if(istype(P, /obj/item/weapon/wrench)) diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 7bc376580b8..8370dd40f3c 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -1,3 +1,7 @@ +/proc/invalidateCameraCache() + for(var/obj/machinery/computer/security/s in world) + s.camera_cache = null + /obj/machinery/computer/security name = "Camera Monitor" desc = "Used to access the various cameras networks on the station." @@ -12,6 +16,7 @@ var/list/tempnets[0] var/list/data[0] var/list/access[0] + var/camera_cache = null New() // Lists existing networks and their required access. Format: networks[] = list() networks["SS13"] = list(access_hos,access_captain) @@ -48,27 +53,23 @@ return 1 // Network configuration - attackby(I as obj, user as mob) + attackby(I as obj, user as mob, params) access = list() - if(istype(I,/obj/item/weapon/card/emag)) // If hit by an emag. - var/obj/item/weapon/card/emag/E = I - if(!emagged) - if(E.uses) - E.uses-- - emagged = 1 - user << "\blue You have authorized full network access!" - ui_interact(user) - else - ui_interact(user) - else - ui_interact(user) - else if(istype(I,/obj/item/weapon/card/id)) // If hit by a regular ID card. + if(istype(I,/obj/item/weapon/card/id)) // If hit by a regular ID card. var/obj/item/weapon/card/id/E = I access = E.access ui_interact(user) else ..() + emag_act(user as mob) + if(!emagged) + emagged = 1 + user << "\blue You have authorized full network access!" + ui_interact(user) + else + ui_interact(user) + ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) if(src.z > 6) return if(stat & (NOPOWER|BROKEN)) return @@ -76,14 +77,15 @@ var/data[0] + data["current"] = null var/list/L = list() - for (var/obj/machinery/camera/C in cameranet.viewpoints) + for (var/obj/machinery/camera/C in cameranet.cameras) if(can_access_camera(C)) L.Add(C) - camera_sort(L) + cameranet.process_sort() var/cameras[0] for(var/obj/machinery/camera/C in L) @@ -106,7 +108,7 @@ if(emagged) access = list(access_captain) // Assume captain level access when emagged data["emagged"] = 1 - if(isAI(user) || isrobot (user)) + if(isAI(user) || isrobot(user)) access = list(access_captain) // Assume captain level access when AI // Loop through the ID's permission, and check which networks the ID has access to. @@ -119,7 +121,7 @@ tempnets.Add(list(list("name" = l, "active" = 0))) break data["networks"] = tempnets - + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "sec_camera.tmpl", "Camera Console", 900, 800) @@ -137,7 +139,7 @@ if(href_list["switchTo"]) if(src.z>6 || stat&(NOPOWER|BROKEN)) return if(usr.stat || ((get_dist(usr, src) > 1 || !( usr.canmove ) || usr.blinded) && !istype(usr, /mob/living/silicon))) return - var/obj/machinery/camera/C = locate(href_list["switchTo"]) in cameranet.viewpoints + var/obj/machinery/camera/C = locate(href_list["switchTo"]) in cameranet.cameras if(!C) return switch_to_camera(usr, C) @@ -197,6 +199,9 @@ else if(isAI(user)) var/mob/living/silicon/ai/A = user + // Only allow non-carded AIs to view because the interaction with the eye gets all wonky otherwise. + if(!A.is_in_chassis()) + return 0 A.eyeobj.setLoc(get_turf(C)) A.client.eye = A.eyeobj else diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index 6298f0d7d89..73931aa0183 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -55,7 +55,7 @@ usr << "There is nothing to remove from the console." return -/obj/machinery/computer/card/attackby(obj/item/weapon/card/id/id_card, mob/user) +/obj/machinery/computer/card/attackby(obj/item/weapon/card/id/id_card, mob/user, params) if(!istype(id_card)) return ..() @@ -198,7 +198,7 @@ if (is_authenticated() && modify) 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 = sanitize(copytext(input("Enter a custom job assignment.","Assignment"),1,MAX_MESSAGE_LEN)) //let custom jobs function as an impromptu alt title, mainly for sechuds if(temp_t && modify) modify.assignment = temp_t diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index c8ae03e2c26..bf28014c6e9 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -73,7 +73,7 @@ return podf -/obj/machinery/computer/cloning/attackby(obj/item/W as obj, mob/user as mob) +/obj/machinery/computer/cloning/attackby(obj/item/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/disk/data)) //INSERT SOME DISKETTES if (!src.diskette) user.drop_item() @@ -155,7 +155,7 @@ /obj/machinery/computer/cloning/Topic(href, href_list) if(..()) - return + return 1 if(loading) return @@ -329,7 +329,7 @@ scantemp = "Error: Mental interface failure." nanomanager.update_uis(src) return - if ((M_NOCLONE in subject.mutations) && src.scanner.scan_level < 2) + if ((NOCLONE in subject.mutations) && src.scanner.scan_level < 2) scantemp = "Error: Mental interface failure." nanomanager.update_uis(src) return diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index e4ecdb12efa..e5aeabf72ae 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -55,14 +55,20 @@ var/shuttle_call/shuttle_calls[0] var/stat_msg1 var/stat_msg2 var/display_type="blank" + + var/datum/announcement/priority/crew_announcement = new l_color = "#0000FF" + +/obj/machinery/computer/communications/New() + ..() + crew_announcement.newscast = 1 /obj/machinery/computer/communications/Topic(href, href_list) if(..(href, href_list)) - return + return 1 - if (!(src.z in list(STATION_Z,CENTCOMM_Z))) + if ((!(src.z in config.station_levels) && !(src.z in config.admin_levels))) usr << "\red Unable to establish a connection: \black You're too far away from the station!" return @@ -83,10 +89,12 @@ var/shuttle_call/shuttle_calls[0] if (I && istype(I)) if(src.check_access(I)) authenticated = 1 - if(20 in I.access) + if(access_captain in I.access) authenticated = 2 + crew_announcement.announcer = GetNameAndAssignmentFromId(I) if("logout") authenticated = 0 + crew_announcement.announcer = "" setMenuState(usr,COMM_SCREEN_MAIN) // ALART LAVUL @@ -127,14 +135,14 @@ var/shuttle_call/shuttle_calls[0] usr << "You need to swipe your ID." if("announce") - if(src.authenticated==2 && !issilicon(usr)) - if(message_cooldown) return - var/input = stripped_input(usr, "Please choose a message to announce to the station crew.", "What?") + if(src.authenticated==2) + if(message_cooldown) + usr << "Please allow at least one minute to pass between announcements" + return + var/input = input(usr, "Please write a message to announce to the station crew.", "Priority Announcement") if(!input || !(usr in view(1,src))) return - captain_announce(input)//This should really tell who is, IE HoP, CE, HoS, RD, Captain - log_say("[key_name(usr)] has made a captain announcement: [input]") - message_admins("[key_name_admin(usr)] has made a captain announcement.", 1) + crew_announcement.Announce(input) message_cooldown = 1 spawn(600)//One minute cooldown message_cooldown = 0 @@ -204,7 +212,7 @@ var/shuttle_call/shuttle_calls[0] if(centcomm_message_cooldown) usr << "Arrays recycling. Please stand by." return - var/input = stripped_input(usr, "Please choose a message to transmit to Centcomm via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "") + var/input = input(usr, "Please choose a message to transmit to Centcomm via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "") if(!input || !(usr in view(1,src))) return Centcomm_announce(input, usr) @@ -240,12 +248,11 @@ var/shuttle_call/shuttle_calls[0] return 1 -/obj/machinery/computer/communications/attackby(var/obj/I as obj, var/mob/user as mob) - if(istype(I,/obj/item/weapon/card/emag/)) +/obj/machinery/computer/communications/emag_act(user as mob) + if(!emagged) src.emagged = 1 user << "You scramble the communication routing circuits!" - ..() - + /obj/machinery/computer/communications/attack_ai(var/mob/user as mob) return src.attack_hand(user) @@ -399,7 +406,7 @@ var/shuttle_call/shuttle_calls[0] return if(emergency_shuttle.going_to_centcom()) - user << "The shuttle may not be called while returning to CentCom." + user << "The shuttle may not be called while returning to Central Command." return if(emergency_shuttle.online()) @@ -409,11 +416,11 @@ var/shuttle_call/shuttle_calls[0] // if force is 0, some things may stop the shuttle call if(!force) if(emergency_shuttle.deny_shuttle) - user << "Centcom does not currently have a shuttle available in your sector. Please try again later." + user << "Central Command does not currently have a shuttle available in your sector. Please try again later." return if(sent_strike_team == 1) - user << "Centcom will not allow the shuttle to be called. Consider all contracts terminated." + user << "Central Command will not allow the shuttle to be called. Consider all contracts terminated." return if(world.time < 54000) // 30 minute grace period to let the game get going @@ -427,8 +434,6 @@ var/shuttle_call/shuttle_calls[0] emergency_shuttle.call_transfer() log_game("[key_name(user)] has called the shuttle.") message_admins("[key_name_admin(user)] has called the shuttle - [formatJumpTo(user)].", 1) - captain_announce("A crew transfer has been initiated. The shuttle has been called. It will arrive in [round(emergency_shuttle.estimate_arrival_time()/60)] minutes.") - return diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index 9dab90e6ed3..14011f549b5 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -102,8 +102,20 @@ stat |= BROKEN update_icon() +/obj/machinery/computer/proc/decode(text) + // Adds line breaks + text = replacetext(text, "\n", "
") + return text + +/obj/machinery/computer/attack_ghost(user as mob) + return src.attack_hand(user) -/obj/machinery/computer/attackby(I as obj, user as mob) +/obj/machinery/computer/attack_hand(user as mob) + /* Observers can view computers, but not actually use them via Topic*/ + if(istype(user, /mob/dead/observer)) return 0 + return ..() + +/obj/machinery/computer/attackby(I as obj, user as mob, params) if(istype(I, /obj/item/weapon/screwdriver) && circuit) playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) if(do_after(user, 20)) @@ -127,8 +139,30 @@ src.attack_hand(user) return +/obj/machinery/computer/attack_paw(mob/living/user) + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) + if(circuit) + if(prob(10)) + user.visible_message("[user.name] smashes the [src.name] with its paws.",\ + "You smash the [src.name] with your paws.",\ + "You hear a smashing sound.") + set_broken() + return + user.visible_message("[user.name] smashes against the [src.name] with its paws.",\ + "You smash against the [src.name] with your paws.",\ + "You hear a clicking sound.") - - - - +/obj/machinery/computer/attack_alien(mob/living/user) + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) + if(circuit) + if(prob(80)) + user.visible_message("[user.name] smashes the [src.name] with its claws.",\ + "You smash the [src.name] with your claws.",\ + "You hear a smashing sound.") + set_broken() + return + user.visible_message("[user.name] smashes against the [src.name] with its claws.",\ + "You smash against the [src.name] with your claws.",\ + "You hear a clicking sound.") diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index a007c324ac4..084eb974688 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -1,18 +1,15 @@ /obj/machinery/computer/crew - name = "Crew Monitoring Computer" + name = "crew monitoring computer" desc = "Used to monitor active health sensors built into most of the crew's uniforms." icon_state = "crew" use_power = 1 idle_power_usage = 250 active_power_usage = 500 circuit = "/obj/item/weapon/circuitboard/crew" - var/list/tracked = list( ) - - l_color = "#0000FF" - + var/obj/nano_module/crew_monitor/crew_monitor /obj/machinery/computer/crew/New() - tracked = list() + crew_monitor = new(src) ..() @@ -27,6 +24,8 @@ return ui_interact(user) +/obj/machinery/computer/crew/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + crew_monitor.ui_interact(user, ui_key, ui, force_open) /obj/machinery/computer/crew/update_icon() @@ -40,99 +39,5 @@ icon_state = initial(icon_state) stat &= ~NOPOWER - -/obj/machinery/computer/crew/Topic(href, href_list) - if(..()) return - if (src.z > 6) - usr << "\red Unable to establish a connection: \black You're too far away from the station!" - return 0 - if( href_list["close"] ) - var/mob/user = usr - var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main") - usr.unset_machine() - ui.close() - return 0 - if(href_list["update"]) - src.updateDialog() - return 1 - /obj/machinery/computer/crew/interact(mob/user) - ui_interact(user) - -/obj/machinery/computer/crew/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - if(stat & (BROKEN|NOPOWER)) - return - user.set_machine(src) - src.scan() - - var/data[0] - var/list/crewmembers = list() - - for(var/obj/item/clothing/under/C in src.tracked) - - - var/turf/pos = get_turf(C) - - if((C) && (C.has_sensor) && (pos) && (pos.z == src.z) && C.sensor_mode) - if(istype(C.loc, /mob/living/carbon/human)) - - var/mob/living/carbon/human/H = C.loc - - var/list/crewmemberData = list() - - crewmemberData["sensor_type"] = C.sensor_mode - crewmemberData["dead"] = H.stat > 1 - crewmemberData["oxy"] = round(H.getOxyLoss(), 1) - crewmemberData["tox"] = round(H.getToxLoss(), 1) - crewmemberData["fire"] = round(H.getFireLoss(), 1) - crewmemberData["brute"] = round(H.getBruteLoss(), 1) - - crewmemberData["name"] = "Unknown" - crewmemberData["rank"] = "Unknown" - if(H.wear_id && istype(H.wear_id, /obj/item/weapon/card/id) ) - var/obj/item/weapon/card/id/I = H.wear_id - crewmemberData["name"] = I.name - crewmemberData["rank"] = I.rank - else if(H.wear_id && istype(H.wear_id, /obj/item/device/pda) ) - var/obj/item/device/pda/P = H.wear_id - crewmemberData["name"] = (P.id ? P.id.name : "Unknown") - crewmemberData["rank"] = (P.id ? P.id.rank : "Unknown") - var/area/A = get_area(H) - crewmemberData["area"] = sanitize(A.name) - crewmemberData["x"] = pos.x - crewmemberData["y"] = pos.y - - // Works around list += list2 merging lists; it's not pretty but it works - crewmembers += "temporary item" - crewmembers[crewmembers.len] = crewmemberData - - crewmembers = sortByKey(crewmembers, "name") - - data["crewmembers"] = crewmembers - - ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "crew_monitor.tmpl", "Crew Monitoring Computer", 900, 800) - - // adding a template with the key "mapContent" enables the map ui functionality - ui.add_template("mapContent", "crew_monitor_map_content.tmpl") - // adding a template with the key "mapHeader" replaces the map header content - ui.add_template("mapHeader", "crew_monitor_map_header.tmpl") - - // we want to show the map by default - ui.set_show_map(1) - - ui.set_initial_data(data) - ui.open() - - // should make the UI auto-update; doesn't seem to? - ui.set_auto_update(1) - - -/obj/machinery/computer/crew/proc/scan() - for(var/mob/living/carbon/human/H in mob_list) - if(istype(H.w_uniform, /obj/item/clothing/under)) - var/obj/item/clothing/under/C = H.w_uniform - if (C.has_sensor) - tracked |= C - return 1 + crew_monitor.ui_interact(user) \ No newline at end of file diff --git a/code/game/machinery/computer/hologram.dm b/code/game/machinery/computer/hologram.dm index e57aa56fe78..ecb3ba58b3d 100644 --- a/code/game/machinery/computer/hologram.dm +++ b/code/game/machinery/computer/hologram.dm @@ -57,7 +57,7 @@ /obj/machinery/computer/hologram_comp/Topic(href, href_list) if(..()) - return + return 1 if (in_range(src, usr)) flick("holo_console1", src) if (href_list["power"]) diff --git a/code/game/machinery/computer/honkputer.dm b/code/game/machinery/computer/honkputer.dm index a5efb1dd2a9..bd9d0344a2c 100644 --- a/code/game/machinery/computer/honkputer.dm +++ b/code/game/machinery/computer/honkputer.dm @@ -16,8 +16,8 @@ /obj/machinery/computer/HONKputer/Topic(href, href_list) if(..()) - return - if (src.z > 1) + return 1 + if (!(src.z in config.station_levels)) usr << "\red Unable to establish a connection: \black You're too far away from the station!" return usr.set_machine(src) @@ -57,12 +57,10 @@ src.updateUsrDialog() -/obj/machinery/computer/HONKputer/attackby(var/obj/I as obj, var/mob/user as mob) - if(istype(I,/obj/item/weapon/card/emag/)) +/obj/machinery/computer/HONKputer/emag_act(user as mob) + if(!emagged) src.emagged = 1 user << "You scramble the login circuits, allowing anyone to use the console!" - ..() - /obj/machinery/computer/HONKputer/attack_hand(var/mob/user as mob) if(..()) @@ -92,7 +90,7 @@ onclose(user, "honkputer") -/obj/machinery/computer/HONKputer/attackby(I as obj, user as mob) +/obj/machinery/computer/HONKputer/attackby(I as obj, user as mob, params) if(istype(I, /obj/item/weapon/screwdriver) && circuit) playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) if(do_after(user, 20)) diff --git a/code/game/machinery/computer/law.dm b/code/game/machinery/computer/law.dm index 47a0951b20e..4802e855af2 100644 --- a/code/game/machinery/computer/law.dm +++ b/code/game/machinery/computer/law.dm @@ -26,7 +26,7 @@ return - attackby(obj/item/weapon/O as obj, mob/user as mob) + attackby(obj/item/weapon/O as obj, mob/user as mob, params) if (user.z > 6) user << "\red Unable to establish a connection: \black You're too far away from the station!" return @@ -53,7 +53,8 @@ usr << "[src.current.name] selected for law changes." return - + attack_ghost(user as mob) + return 1 /obj/machinery/computer/borgupload name = "Cyborg Upload" @@ -63,7 +64,7 @@ var/mob/living/silicon/robot/current = null - attackby(obj/item/weapon/aiModule/module as obj, mob/user as mob) + attackby(obj/item/weapon/aiModule/module as obj, mob/user as mob, params) if(istype(module, /obj/item/weapon/aiModule)) module.install(src) else @@ -85,3 +86,6 @@ else usr << "[src.current.name] selected for law changes." return + + attack_ghost(user as mob) + return 1 diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index 1d9cee6a55b..23a8c3ed16f 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -128,7 +128,7 @@ /obj/machinery/computer/med_data/Topic(href, href_list) if(..()) - return + return 1 if (!( data_core.general.Find(src.active1) )) src.active1 = null diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm index 73c469d6db4..3cf15c5308a 100644 --- a/code/game/machinery/computer/message.dm +++ b/code/game/machinery/computer/message.dm @@ -36,29 +36,11 @@ l_color = "#50AB00" -/obj/machinery/computer/message_monitor/attackby(obj/item/weapon/O as obj, mob/living/user as mob) +/obj/machinery/computer/message_monitor/attackby(obj/item/weapon/O as obj, mob/living/user as mob, params) if(stat & (NOPOWER|BROKEN)) return if(!istype(user)) return - if(istype(O,/obj/item/weapon/card/emag/)) - // Will create sparks and print out the console's password. You will then have to wait a while for the console to be back online. - // It'll take more time if there's more characters in the password.. - if(!emag) - if(!isnull(src.linkedServer)) - icon_state = hack_icon // An error screen I made in the computers.dmi - emag = 1 - screen = 2 - spark_system.set_up(5, 0, src) - src.spark_system.start() - var/obj/item/weapon/paper/monitorkey/MK = new/obj/item/weapon/paper/monitorkey - MK.loc = src.loc - // Will help make emagging the console not so easy to get away with. - MK.info += "

£%@%(*$%&(£&?*(%&£/{}" - spawn(100*length(src.linkedServer.decryptkey)) UnmagConsole() - message = rebootmsg - else - user << "A no server error appears on the screen." if(isscrewdriver(O) && emag) //Stops people from just unscrewing the monitor and putting it back to get the console working again. user << "It is too hot to mess with!" @@ -66,6 +48,25 @@ ..() return + +/obj/machinery/computer/message_monitor/emag_act(user as mob) + // Will create sparks and print out the console's password. You will then have to wait a while for the console to be back online. + // It'll take more time if there's more characters in the password.. + if(!emag) + if(!isnull(src.linkedServer)) + icon_state = hack_icon // An error screen I made in the computers.dmi + emag = 1 + screen = 2 + spark_system.set_up(5, 0, src) + src.spark_system.start() + var/obj/item/weapon/paper/monitorkey/MK = new/obj/item/weapon/paper/monitorkey + MK.loc = src.loc + // Will help make emagging the console not so easy to get away with. + MK.info += "

£%@%(*$%&(£&?*(%&£/{}" + spawn(100*length(src.linkedServer.decryptkey)) UnmagConsole() + message = rebootmsg + else + user << "A no server error appears on the screen." /obj/machinery/computer/message_monitor/update_icon() ..() @@ -274,7 +275,7 @@ /obj/machinery/computer/message_monitor/Topic(href, href_list) if(..()) - return + return 1 if(stat & (NOPOWER|BROKEN)) return if(!istype(usr, /mob/living)) @@ -421,7 +422,7 @@ //Enter message if("Message") custommessage = input(usr, "Please enter your message.") as text|null - custommessage = copytext(sanitize(custommessage), 1, MAX_MESSAGE_LEN) + custommessage = sanitize(copytext(custommessage, 1, MAX_MESSAGE_LEN)) //Send message if("Send") diff --git a/code/game/machinery/computer/pod.dm b/code/game/machinery/computer/pod.dm index 2f408817802..69c68ecf8aa 100644 --- a/code/game/machinery/computer/pod.dm +++ b/code/game/machinery/computer/pod.dm @@ -50,7 +50,7 @@ return /* -/obj/machinery/computer/pod/attackby(I as obj, user as mob) +/obj/machinery/computer/pod/attackby(I as obj, user as mob, params) if(istype(I, /obj/item/weapon/screwdriver)) playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1) if(do_after(user, 20)) @@ -163,7 +163,7 @@ /obj/machinery/computer/pod/Topic(href, href_list) if(..()) - return + return 1 if((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon))) usr.set_machine(src) if(href_list["power"]) diff --git a/code/game/machinery/computer/power.dm b/code/game/machinery/computer/power.dm index 65eb7ce4bc3..06f8cfe5692 100644 --- a/code/game/machinery/computer/power.dm +++ b/code/game/machinery/computer/power.dm @@ -23,15 +23,14 @@ if(isturf(T)) attached = locate() in T if(attached) - powernet = attached.get_powernet() - - + powernet = attached.get_powernet() + /obj/machinery/power/monitor/attack_ai(mob/user) add_fingerprint(user) if(stat & (BROKEN|NOPOWER)) return - interact(user) + interact(user) /obj/machinery/power/monitor/attack_hand(mob/user) add_fingerprint(user) @@ -40,7 +39,7 @@ return interact(user) -/obj/machinery/power/monitor/attackby(I as obj, user as mob) +/obj/machinery/power/monitor/attackby(I as obj, user as mob, params) if(istype(I, /obj/item/weapon/screwdriver)) playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) if(do_after(user, 20)) @@ -133,7 +132,8 @@ /obj/machinery/power/monitor/Topic(href, href_list) - ..() + if(..()) + return 1 if( href_list["close"] ) usr << browse(null, "window=powcomp") usr.unset_machine() diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm index 11b71274ca6..7b4b37665b0 100644 --- a/code/game/machinery/computer/prisoner.dm +++ b/code/game/machinery/computer/prisoner.dm @@ -65,7 +65,7 @@ if(!T.implanted) continue var/loc_display = "Unknown" var/mob/living/carbon/M = T.imp_in - if(M.z == 1 && !istype(M.loc, /turf/space)) + if((M.z in config.station_levels) && !istype(M.loc, /turf/space)) var/turf/mob_loc = get_turf_loc(M) loc_display = mob_loc.loc if(T.malfunction) @@ -129,7 +129,7 @@ usr << "Unauthorized Access." else if(href_list["warn"]) - var/warning = copytext(sanitize(input(usr,"Message:","Enter your message here!","")),1,MAX_MESSAGE_LEN) + var/warning = sanitize(copytext(input(usr,"Message:","Enter your message here!",""),1,MAX_MESSAGE_LEN)) if(!warning) return var/obj/item/weapon/implant/I = locate(href_list["warn"]) if((I)&&(I.imp_in)) diff --git a/code/game/machinery/computer/prisonshuttle.dm b/code/game/machinery/computer/prisonshuttle.dm index 9ce03c4630d..a5837969741 100644 --- a/code/game/machinery/computer/prisonshuttle.dm +++ b/code/game/machinery/computer/prisonshuttle.dm @@ -22,7 +22,7 @@ var/prison_shuttle_timeleft = 0 var/prison_break = 0 - attackby(I as obj, user as mob) + attackby(I as obj, user as mob, params) return src.attack_hand(user) @@ -34,7 +34,7 @@ var/prison_shuttle_timeleft = 0 return src.attack_hand(user) - attackby(I as obj, user as mob) + attackby(I as obj, user as mob, params) if(istype(I, /obj/item/weapon/screwdriver)) playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) if(do_after(user, 20)) diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm index 35552231640..7692b31e3e4 100644 --- a/code/game/machinery/computer/robot.dm +++ b/code/game/machinery/computer/robot.dm @@ -106,7 +106,7 @@ /obj/machinery/computer/robotics/Topic(href, href_list) if(..()) - return + return 1 if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) usr.set_machine(src) @@ -123,7 +123,7 @@ if (istype(I)) if(src.check_access(I)) if (!status) - message_admins("\blue [key_name_admin(usr)] has initiated the global cyborg killswitch!") + msg_admin_attack("\blue [key_name_admin(usr)] has initiated the global cyborg killswitch!") log_game("\blue [key_name(usr)] has initiated the global cyborg killswitch!") use_log += text("\[[time_stamp()]\] [usr.name] ([usr.ckey]) has initiated the global cyborg killswitch!") src.status = 1 @@ -169,7 +169,7 @@ R.ResetSecurityCodes() else - message_admins("\blue [key_name_admin(usr)] detonated [R.name]!") + msg_admin_attack("\blue [key_name_admin(usr)] detonated [R.name]!") log_game("\blue [key_name_admin(usr)] detonated [R.name]!") use_log += text("\[[time_stamp()]\] [usr.name] ([usr.ckey]) detonated [R.name] ([R.ckey])!") R.self_destruct() @@ -183,7 +183,7 @@ var/choice = input("Are you certain you wish to [R.canmove ? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort") if(choice == "Confirm") if(R && istype(R)) - message_admins("\blue [key_name_admin(usr)] [R.canmove ? "locked down" : "released"] [R.name]!") + msg_admin_attack("\blue [key_name_admin(usr)] [R.canmove ? "locked down" : "released"] [R.name]!") log_game("[key_name(usr)] [R.canmove ? "locked down" : "released"] [R.name]!") R.canmove = !R.canmove if (R.lockcharge) @@ -208,7 +208,7 @@ var/choice = input("Are you certain you wish to hack [R.name]?") in list("Confirm", "Abort") if(choice == "Confirm") if(R && istype(R)) -// message_admins("\blue [key_name_admin(usr)] emagged [R.name] using robotic console!") + msg_admin_attack("\blue [key_name_admin(usr)] emagged [R.name] using robotic console!") log_game("[key_name(usr)] emagged [R.name] using robotic console!") R.emagged = 1 if(R.hud_used) diff --git a/code/game/machinery/computer/salvage_ship.dm b/code/game/machinery/computer/salvage_ship.dm index a54340da4de..5e0feda0c20 100644 --- a/code/game/machinery/computer/salvage_ship.dm +++ b/code/game/machinery/computer/salvage_ship.dm @@ -36,7 +36,7 @@ return 1 -/obj/machinery/computer/salvage_ship/attackby(obj/item/I as obj, mob/user as mob) +/obj/machinery/computer/salvage_ship/attackby(obj/item/I as obj, mob/user as mob, params) return attack_hand(user) /obj/machinery/computer/salvage_ship/attack_ai(mob/user as mob) @@ -75,6 +75,8 @@ /obj/machinery/computer/salvage_ship/Topic(href, href_list) + if(..()) + return 1 if(!isliving(usr)) return var/mob/living/user = usr diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index ce9b239da49..1094ede2762 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -25,7 +25,7 @@ l_color = "#B40000" -/obj/machinery/computer/secure_data/attackby(obj/item/O as obj, user as mob) +/obj/machinery/computer/secure_data/attackby(obj/item/O as obj, user as mob, params) if(istype(O, /obj/item/weapon/card/id) && !scan) usr.drop_item() O.loc = src @@ -208,7 +208,7 @@ I can't be bothered to look more of the actual code outside of switch but that p What a mess.*/ /obj/machinery/computer/secure_data/Topic(href, href_list) if(..()) - return + return 1 if (!( data_core.general.Find(active1) )) active1 = null if (!( data_core.security.Find(active2) )) diff --git a/code/game/machinery/computer/shuttle.dm b/code/game/machinery/computer/shuttle.dm index 0815cf7932a..ee4a88fb89b 100644 --- a/code/game/machinery/computer/shuttle.dm +++ b/code/game/machinery/computer/shuttle.dm @@ -8,7 +8,7 @@ l_color = "#7BF9FF" - attackby(var/obj/item/weapon/card/W as obj, var/mob/user as mob) + attackby(var/obj/item/weapon/card/W as obj, var/mob/user as mob, params) if(stat & (BROKEN|NOPOWER)) return if ((!( istype(W, /obj/item/weapon/card) ) || !( ticker ) || emergency_shuttle.location() || !( user ))) return if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) @@ -56,11 +56,13 @@ world << "\blue All authorizations to shortening time for shuttle launch have been revoked!" src.authorized.len = 0 src.authorized = list( ) - - else if (istype(W, /obj/item/weapon/card/emag) && !emagged) + return + + emag_act(user as mob) + if (!emagged) var/choice = alert(user, "Would you like to launch the shuttle?","Shuttle control", "Launch", "Cancel") - if(!emagged && !emergency_shuttle.location() && user.get_active_hand() == W) + if(!emagged && !emergency_shuttle.location()) switch(choice) if("Launch") world << "\blue Alert: Shuttle launch time shortened to 10 seconds!" @@ -68,4 +70,3 @@ emagged = 1 if("Cancel") return - return diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm index 3b6a530f490..9f1781519ae 100644 --- a/code/game/machinery/computer/skills.dm +++ b/code/game/machinery/computer/skills.dm @@ -22,7 +22,7 @@ var/order = 1 // -1 = Descending - 1 = Ascending -/obj/machinery/computer/skills/attackby(obj/item/O as obj, user as mob) +/obj/machinery/computer/skills/attackby(obj/item/O as obj, user as mob, params) if(istype(O, /obj/item/weapon/card/id) && !scan) usr.drop_item() O.loc = src @@ -151,7 +151,7 @@ I can't be bothered to look more of the actual code outside of switch but that p What a mess.*/ /obj/machinery/computer/skills/Topic(href, href_list) if(..()) - return + return 1 if (!( data_core.general.Find(active1) )) active1 = null if ((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon))) diff --git a/code/game/machinery/computer/specops_shuttle.dm b/code/game/machinery/computer/specops_shuttle.dm index bdfa06eeba4..68ded19320d 100644 --- a/code/game/machinery/computer/specops_shuttle.dm +++ b/code/game/machinery/computer/specops_shuttle.dm @@ -252,7 +252,7 @@ var/specops_shuttle_timeleft = 0 /obj/machinery/computer/specops_shuttle/attack_paw(var/mob/user as mob) return attack_hand(user) -/obj/machinery/computer/specops_shuttle/attackby(I as obj, user as mob) +/obj/machinery/computer/specops_shuttle/attackby(I as obj, user as mob, params) if(istype(I,/obj/item/weapon/card/emag)) user << "\blue The electronic systems in this console are far too advanced for your primitive hacking peripherals." else @@ -287,7 +287,7 @@ var/specops_shuttle_timeleft = 0 /obj/machinery/computer/specops_shuttle/Topic(href, href_list) if(..()) - return + return 1 if ((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon))) usr.machine = src diff --git a/code/game/machinery/computer/store.dm b/code/game/machinery/computer/store.dm index 31981544e62..9ab45f15d94 100644 --- a/code/game/machinery/computer/store.dm +++ b/code/game/machinery/computer/store.dm @@ -128,7 +128,7 @@ td.cost.toomuch { /obj/machinery/computer/merch/Topic(href, href_list) if(..()) - return + return 1 //testing(href) diff --git a/code/game/machinery/computer/syndicate_specops_shuttle.dm b/code/game/machinery/computer/syndicate_specops_shuttle.dm index a095dc495f0..288fa2dfdf6 100644 --- a/code/game/machinery/computer/syndicate_specops_shuttle.dm +++ b/code/game/machinery/computer/syndicate_specops_shuttle.dm @@ -176,7 +176,7 @@ var/syndicate_elite_shuttle_timeleft = 0 if(syndicate_elite_shuttle_moving_to_station || syndicate_elite_shuttle_moving_to_mothership) return 0 else return 1 -/obj/machinery/computer/syndicate_elite_shuttle/attackby(I as obj, user as mob) +/obj/machinery/computer/syndicate_elite_shuttle/attackby(I as obj, user as mob, params) return attack_hand(user) /obj/machinery/computer/syndicate_elite_shuttle/attack_ai(var/mob/user as mob) @@ -186,7 +186,7 @@ var/syndicate_elite_shuttle_timeleft = 0 /obj/machinery/computer/syndicate_elite_shuttle/attack_paw(var/mob/user as mob) return attack_hand(user) -/obj/machinery/computer/syndicate_elite_shuttle/attackby(I as obj, user as mob) +/obj/machinery/computer/syndicate_elite_shuttle/attackby(I as obj, user as mob, params) if(istype(I,/obj/item/weapon/card/emag)) user << "\blue The electronic systems in this console are far too advanced for your primitive hacking peripherals." else @@ -220,7 +220,7 @@ var/syndicate_elite_shuttle_timeleft = 0 /obj/machinery/computer/syndicate_elite_shuttle/Topic(href, href_list) if(..()) - return + return 1 if ((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon))) usr.set_machine(src) diff --git a/code/game/machinery/computer/telecrystalconsoles.dm b/code/game/machinery/computer/telecrystalconsoles.dm index ae076b34349..f65ad4aae49 100644 --- a/code/game/machinery/computer/telecrystalconsoles.dm +++ b/code/game/machinery/computer/telecrystalconsoles.dm @@ -29,7 +29,7 @@ var/list/possible_uplinker_IDs = list("Alfa","Bravo","Charlie","Delta","Echo","F name = "[name] [rand(1,999)]" -/obj/machinery/computer/telecrystals/uplinker/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/machinery/computer/telecrystals/uplinker/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(istype(O, /obj/item)) if(uplinkholder) @@ -106,7 +106,7 @@ var/list/possible_uplinker_IDs = list("Alfa","Bravo","Charlie","Delta","Echo","F /obj/machinery/computer/telecrystals/uplinker/Topic(href, href_list) if(..()) - return + return 1 if(href_list["donate1"]) donateTC(1) diff --git a/code/game/machinery/computer/xenos_shuttle.dm b/code/game/machinery/computer/xenos_shuttle.dm index 1944274965a..343c2717b76 100644 --- a/code/game/machinery/computer/xenos_shuttle.dm +++ b/code/game/machinery/computer/xenos_shuttle.dm @@ -85,7 +85,7 @@ return 1 -/obj/machinery/computer/xenos_station/attackby(obj/item/I as obj, mob/user as mob) +/obj/machinery/computer/xenos_station/attackby(obj/item/I as obj, mob/user as mob, params) return attack_hand(user) /obj/machinery/computer/xenos_station/attack_ai(mob/user as mob) @@ -93,6 +93,9 @@ /obj/machinery/computer/xenos_station/attack_paw(mob/user as mob) return attack_hand(user) + +/obj/machinery/computer/xenos_station/attack_alien(mob/user as mob) + return attack_hand(user) /obj/machinery/computer/xenos_station/attack_hand(mob/user as mob) if(!allowed(user)) @@ -123,6 +126,9 @@ /obj/machinery/computer/xenos_station/Topic(href, href_list) + if(..()) + return 1 + if(!isliving(usr)) return var/mob/living/user = usr diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index c108e02822c..546b5956f0b 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -92,7 +92,7 @@ else desc += "." -/obj/machinery/constructable_frame/machine_frame/attackby(obj/item/P as obj, mob/user as mob) +/obj/machinery/constructable_frame/machine_frame/attackby(obj/item/P as obj, mob/user as mob, params) if(P.crit_fail) user << "This part is faulty, you cannot add this to the machine!" return @@ -270,7 +270,7 @@ to destroy them and players will be able to make replacements. /obj/machinery/vending/suitdispenser = "Suitlord 9000", /obj/machinery/vending/shoedispenser = "Shoelord 9000") -/obj/item/weapon/circuitboard/vendor/attackby(obj/item/I, mob/user) +/obj/item/weapon/circuitboard/vendor/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/weapon/screwdriver)) set_type(pick(names_paths), user) @@ -289,7 +289,7 @@ to destroy them and players will be able to make replacements. frame_desc = "Requires 5 pieces of cable, 5 Power Cells and 1 Capacitor." req_components = list( /obj/item/stack/cable_coil = 5, - /obj/item/weapon/cell = 5, + /obj/item/weapon/stock_parts/cell = 5, /obj/item/weapon/stock_parts/capacitor = 1) @@ -306,7 +306,7 @@ to destroy them and players will be able to make replacements. /obj/item/stack/cable_coil = 1, /obj/item/weapon/stock_parts/console_screen = 1) -/obj/item/weapon/circuitboard/thermomachine/attackby(obj/item/I, mob/user) +/obj/item/weapon/circuitboard/thermomachine/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/weapon/screwdriver)) if(build_path == /obj/machinery/atmospherics/unary/cold_sink/freezer) build_path = /obj/machinery/atmospherics/unary/heat_reservoir/heater @@ -361,7 +361,7 @@ to destroy them and players will be able to make replacements. /obj/item/weapon/stock_parts/capacitor = 1, /obj/item/weapon/stock_parts/manipulator = 1, /obj/item/weapon/stock_parts/console_screen = 1, - /obj/item/weapon/cell = 1) + /obj/item/weapon/stock_parts/cell = 1) /obj/item/weapon/circuitboard/destructive_analyzer name = "Circuit board (Destructive Analyzer)" @@ -583,7 +583,7 @@ obj/item/weapon/circuitboard/rdserver frame_desc = "Requires 2 Capacitors, 1 Power Cell and 1 Manipulator." req_components = list( /obj/item/weapon/stock_parts/capacitor = 2, - /obj/item/weapon/cell = 1, + /obj/item/weapon/stock_parts/cell = 1, /obj/item/weapon/stock_parts/manipulator = 1) // Telecomms circuit boards: diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index dc738ad2139..0d92be24127 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -5,6 +5,7 @@ density = 1 anchored = 1.0 layer = 2.8 + interact_offline = 1 var/on = 0 var/temperature_archived @@ -77,7 +78,7 @@ return if(user.restrained() || user.stat || user.weakened || user.stunned || user.paralysis || user.resting) //are you cuffed, dying, lying, stunned or other return - if(O.anchored || get_dist(user, src) > 1 || get_dist(user, O) > 1 || user.contents.Find(src)) // is the mob anchored, too far away from you, or are you too far away from the source + if(get_dist(user, src) > 1 || get_dist(user, O) > 1 || user.contents.Find(src)) // is the mob anchored, too far away from you, or are you too far away from the source return if(!ismob(O)) //humans only return @@ -125,7 +126,6 @@ if(!node) return if(!on) - updateUsrDialog() return if(occupant) @@ -140,7 +140,6 @@ if(abs(temperature_archived-air_contents.temperature) > 1) network.update = 1 - updateUsrDialog() return 1 @@ -220,12 +219,14 @@ for(var/datum/reagent/R in beaker.reagents.reagent_list) data["beakerVolume"] += R.volume + data["autoeject"] = autoeject + // update the ui if it exists, returns null if no ui is passed/found ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) // the ui does not exist, so we'll create a new() one // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "cryo.tmpl", "Cryo Cell Control System", 520, 410) + ui = new(user, src, ui_key, "cryo.tmpl", "Cryo Cell Control System", 520, 420) // when the ui is first opened this is the data it will use ui.set_initial_data(data) // open the new ui window @@ -267,7 +268,7 @@ add_fingerprint(usr) return 1 // update UIs attached to this object -/obj/machinery/atmospherics/unary/cryo_cell/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob) +/obj/machinery/atmospherics/unary/cryo_cell/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob, params) if(istype(G, /obj/item/weapon/reagent_containers/glass)) if(beaker) user << "\red A beaker is already loaded into the machine." @@ -303,7 +304,6 @@ var/mob/M = G:affecting if(put_mob(M)) del(G) - updateUsrDialog() return /obj/machinery/atmospherics/unary/cryo_cell/update_icon() diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 91dbbae40b3..dec81660ef4 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -65,9 +65,8 @@ onclose(user, "cryopod_console") /obj/machinery/computer/cryopod/Topic(href, href_list) - if(..()) - return + return 1 var/mob/user = usr @@ -200,7 +199,7 @@ /obj/item/clothing/shoes/magboots, /obj/item/blueprints, /obj/item/clothing/head/helmet/space, - /obj/item/weapon/tank + /obj/item/weapon/storage/internal ) /obj/machinery/cryopod/right @@ -284,7 +283,7 @@ /obj/machinery/cryopod/robot/despawn_occupant() var/mob/living/silicon/robot/R = occupant if(!istype(R)) return ..() - + R.contents -= R.mmi del(R.mmi) for(var/obj/item/I in R.module) // the tools the borg has; metal, glass, guns etc @@ -300,7 +299,7 @@ /obj/machinery/cryopod/proc/despawn_occupant() //Drop all items into the pod. for(var/obj/item/W in occupant) - occupant.drop_from_inventory(W) + occupant.unEquip(W) W.loc = src if(W.contents.len) //Make sure we catch anything not handled by del() on the items. @@ -389,7 +388,7 @@ //Make an announcement and log the person entering storage. control_computer.frozen_crew += "[occupant.real_name]" - + var/ailist[] = list() for (var/mob/living/silicon/ai/A in living_mob_list) ailist += A @@ -398,7 +397,7 @@ announcer.say(";[occupant.real_name] [on_store_message]") else announce.autosay("[occupant.real_name] [on_store_message]", "[on_store_name]") - + visible_message("\The [src] hums and hisses as it moves [occupant.real_name] into storage.", 3) // Delete the mob. @@ -407,7 +406,7 @@ name = initial(name) -/obj/machinery/cryopod/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob) +/obj/machinery/cryopod/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob, params) if(istype(G, /obj/item/weapon/grab)) @@ -461,7 +460,7 @@ //Despawning occurs when process() is called with an occupant without a client. src.add_fingerprint(M) - + /obj/machinery/cryopod/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob) @@ -469,7 +468,7 @@ return if(user.restrained() || user.stat || user.weakened || user.stunned || user.paralysis || user.resting) //are you cuffed, dying, lying, stunned or other return - if(O.anchored || get_dist(user, src) > 1 || get_dist(user, O) > 1 || user.contents.Find(src)) // is the mob anchored, too far away from you, or are you too far away from the source + if(get_dist(user, src) > 1 || get_dist(user, O) > 1 || user.contents.Find(src)) // is the mob anchored, too far away from you, or are you too far away from the source return if(!ismob(O)) //humans only return diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index c00668a7276..8cde409e649 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -65,7 +65,7 @@ for reference: var/health = 100.0 var/maxhealth = 100.0 - attackby(obj/item/W as obj, mob/user as mob) + attackby(obj/item/W as obj, mob/user as mob, params) if (istype(W, /obj/item/stack/sheet/wood)) if (src.health < src.maxhealth) visible_message("\red [user] begins to repair the [src]!") @@ -157,8 +157,8 @@ for reference: src.icon_state = "barrier[src.locked]" - attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/card/id/)) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) + if (istype(W, /obj/item/weapon/card/id)) if (src.allowed(user)) if (src.emagged < 2.0) src.locked = !src.locked @@ -177,24 +177,6 @@ for reference: visible_message("\red BZZzZZzZZzZT") return return - else if (istype(W, /obj/item/weapon/card/emag)) - if (src.emagged == 0) - src.emagged = 1 - src.req_access = null - user << "You break the ID authentication lock on the [src]." - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(2, 1, src) - s.start() - visible_message("\red BZZzZZzZZzZT") - return - else if (src.emagged == 1) - src.emagged = 2 - user << "You short out the anchoring mechanism on the [src]." - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(2, 1, src) - s.start() - visible_message("\red BZZzZZzZZzZT") - return else if (istype(W, /obj/item/weapon/wrench)) if (src.health < src.maxhealth) src.health = src.maxhealth @@ -218,6 +200,23 @@ for reference: if (src.health <= 0) src.explode() ..() + + emag_act(user as mob) + if (!emagged) + emagged = 1 + req_access = null + user << "You break the ID authentication lock on the [src]." + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 1, src) + s.start() + visible_message("\red BZZzZZzZZzZT") + else if (src.emagged == 1) + src.emagged = 2 + user << "You short out the anchoring mechanism on the [src]." + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 1, src) + s.start() + visible_message("\red BZZzZZzZZzZT") ex_act(severity) switch(severity) diff --git a/code/game/machinery/door_control.dm b/code/game/machinery/door_control.dm index 2dcb0c0b2e0..50d6eb49a0f 100644 --- a/code/game/machinery/door_control.dm +++ b/code/game/machinery/door_control.dm @@ -40,7 +40,7 @@ /obj/machinery/door_control/attack_paw(mob/user as mob) return src.attack_hand(user) -/obj/machinery/door_control/attackby(obj/item/weapon/W, mob/user as mob) +/obj/machinery/door_control/attackby(obj/item/weapon/W, mob/user as mob, params) /* For later implementation if (istype(W, /obj/item/weapon/screwdriver)) { @@ -57,11 +57,14 @@ */ if(istype(W, /obj/item/device/detective_scanner)) return - if(istype(W, /obj/item/weapon/card/emag)) + return src.attack_hand(user) + +/obj/machinery/door_control/emag_act(user as mob) + if(!emagged) + emagged = 1 req_access = list() req_one_access = list() playsound(src.loc, "sparks", 100, 1) - return src.attack_hand(user) /obj/machinery/door_control/attack_hand(mob/user as mob) src.add_fingerprint(usr) @@ -139,7 +142,7 @@ /obj/machinery/driver_button/attack_paw(mob/user as mob) return src.attack_hand(user) -/obj/machinery/driver_button/attackby(obj/item/weapon/W, mob/user as mob) +/obj/machinery/driver_button/attackby(obj/item/weapon/W, mob/user as mob, params) if(istype(W, /obj/item/device/detective_scanner)) return diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 9ec64ff61c5..1582c0cd6a7 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -258,6 +258,10 @@ icon = 'icons/obj/doors/Doorbananium.dmi' mineral = "clown" +/obj/machinery/door/airlock/mime + name = "Airlock" + icon = 'icons/obj/doors/Doorfreezer.dmi' + /obj/machinery/door/airlock/sandstone name = "Sandstone Airlock" icon = 'icons/obj/doors/Doorsand.dmi' @@ -298,7 +302,7 @@ user << "You do not know how to operate this airlock's mechanism." return -/obj/machinery/door/airlock/alien/attackby(C as obj, mob/user as mob) +/obj/machinery/door/airlock/alien/attackby(C as obj, mob/user as mob, params) if(isalien(user) || isrobot(user) || isAI(user)) ..(C, user) else @@ -358,7 +362,7 @@ About the new airlock wires panel: return ((src.aiControlDisabled==1) && (!hackProof) && (!src.isAllPowerLoss())); /obj/machinery/door/airlock/proc/arePowerSystemsOn() - if (stat & NOPOWER) + if (stat & (NOPOWER|BROKEN)) return 0 return (src.secondsMainPowerLost==0 || src.secondsBackupPowerLost==0) @@ -473,7 +477,8 @@ About the new airlock wires panel: if("spark") flick("door_spark", src) if("deny") - flick("door_deny", src) + if(density && src.arePowerSystemsOn()) + flick("door_deny", src) return /obj/machinery/door/airlock/attack_ai(mob/user as mob) @@ -695,16 +700,13 @@ About the new airlock wires panel: //AI //aiDisable - 1 idscan, 2 disrupt main power, 3 disrupt backup power, 4 drop door bolts, 5 un-electrify door, 7 close door, 8 door safties, 9 door speed, 11 emergency access //aiEnable - 1 idscan, 4 raise door bolts, 5 electrify door for 30 seconds, 6 electrify door indefinitely, 7 open door, 8 door safties, 9 door speed, 11 emergency access - if(!nowindow) - ..() - if(usr.stat || usr.restrained()|| usr.small) - return - add_fingerprint(usr) + if(..()) + return 1 if(href_list["close"]) usr << browse(null, "window=airlock") if(usr.machine==src) usr.unset_machine() - return + return 1 if((in_range(src, usr) && istype(src.loc, /turf)) && src.p_open) usr.set_machine(src) @@ -753,7 +755,7 @@ About the new airlock wires panel: if(istype(usr, /mob/living/silicon)) if (!check_synth_access(usr)) - return + return 1 //AI //aiDisable - 1 idscan, 2 disrupt main power, 3 disrupt backup power, 4 drop door bolts, 5 un-electrify door, 7 close door, 8 door safties, 9 door speed @@ -943,9 +945,9 @@ About the new airlock wires panel: update_icon() if(!nowindow) updateUsrDialog() - return + return 0 -/obj/machinery/door/airlock/attackby(C as obj, mob/user as mob) +/obj/machinery/door/airlock/attackby(C as obj, mob/user as mob, params) //world << text("airlock attackby src [] obj [] mob []", src, C, user) if(!istype(usr, /mob/living/silicon)) if(src.isElectrified()) @@ -1031,26 +1033,26 @@ About the new airlock wires panel: if(density) if(beingcrowbarred == 0) //being fireaxe'd var/obj/item/weapon/twohanded/fireaxe/F = C - if(F:wielded) + if(F.wielded) spawn(0) open(1) else - user << "\red You need to be wielding the Fire axe to do that." + user << "\red You need to be wielding \the [C] to do that." else spawn(0) open(1) else if(beingcrowbarred == 0) var/obj/item/weapon/twohanded/fireaxe/F = C - if(F:wielded) + if(F.wielded) spawn(0) close(1) else - user << "\red You need to be wielding the Fire axe to do that." + user << "\red You need to be wielding \the [C] to do that." else spawn(0) close(1) else ..() return -/obj/machinery/door/airlock/plasma/attackby(C as obj, mob/user as mob) +/obj/machinery/door/airlock/plasma/attackby(C as obj, mob/user as mob, params) if(C) ignite(is_hot(C)) ..() @@ -1068,6 +1070,7 @@ About the new airlock wires panel: playsound(src.loc, 'sound/machines/windowdoor.ogg', 100, 1) else if(istype(src, /obj/machinery/door/airlock/clown)) playsound(src.loc, 'sound/items/bikehorn.ogg', 30, 1) + else if(istype(src, /obj/machinery/door/airlock/mime)) else playsound(src.loc, 'sound/machines/airlock.ogg', 30, 1) if(src.closeOther != null && istype(src.closeOther, /obj/machinery/door/airlock/) && !src.closeOther.density) @@ -1104,6 +1107,7 @@ About the new airlock wires panel: playsound(src.loc, 'sound/machines/windowdoor.ogg', 30, 1) else if(istype(src, /obj/machinery/door/airlock/clown)) playsound(src.loc, 'sound/items/bikehorn.ogg', 30, 1) + else if(istype(src, /obj/machinery/door/airlock/mime)) else playsound(get_turf(src), 'sound/machines/airlock.ogg', 30, 1) @@ -1176,7 +1180,7 @@ About the new airlock wires panel: return -/obj/machinery/door/airlock/hatch/gamma/attackby(C as obj, mob/user as mob) +/obj/machinery/door/airlock/hatch/gamma/attackby(C as obj, mob/user as mob, params) //world << text("airlock attackby src [] obj [] mob []", src, C, user) if(!istype(usr, /mob/living/silicon)) if(src.isElectrified()) @@ -1209,7 +1213,7 @@ About the new airlock wires panel: return -/obj/machinery/door/airlock/highsecurity/red/attackby(C as obj, mob/user as mob) +/obj/machinery/door/airlock/highsecurity/red/attackby(C as obj, mob/user as mob, params) //world << text("airlock attackby src [] obj [] mob []", src, C, user) if(!istype(usr, /mob/living/silicon)) if(src.isElectrified()) diff --git a/code/game/machinery/doors/airlock_control.dm b/code/game/machinery/doors/airlock_control.dm index 498d7449a36..fef0ef7d66b 100644 --- a/code/game/machinery/doors/airlock_control.dm +++ b/code/game/machinery/doors/airlock_control.dm @@ -8,11 +8,6 @@ obj/machinery/door/airlock var/datum/radio_frequency/radio_connection var/cur_command = null //the command the door is currently attempting to complete -obj/machinery/door/airlock/proc/can_radio() - if(!arePowerSystemsOn()) - return 0 - return 1 - obj/machinery/door/airlock/process() ..() if (arePowerSystemsOn()) @@ -21,14 +16,13 @@ obj/machinery/door/airlock/process() obj/machinery/door/airlock/receive_signal(datum/signal/signal) if (!arePowerSystemsOn()) return //no power - if (!can_radio()) return //no radio - if(!signal || signal.encryption) return if(id_tag != signal.data["tag"] || !signal.data["command"]) return cur_command = signal.data["command"] - execute_current_command() + spawn() + execute_current_command() obj/machinery/door/airlock/proc/execute_current_command() if(operating) @@ -94,7 +88,7 @@ obj/machinery/door/airlock/proc/command_completed(var/command) return 1 //Unknown command. Just assume it's completed. -obj/machinery/door/airlock/proc/send_status() +obj/machinery/door/airlock/proc/send_status(var/bumped = 0) if(radio_connection) var/datum/signal/signal = new signal.transmission_method = 1 //radio signal @@ -103,6 +97,9 @@ obj/machinery/door/airlock/proc/send_status() signal.data["door_status"] = density?("closed"):("open") signal.data["lock_status"] = locked?("locked"):("unlocked") + + if (bumped) + signal.data["bumped_with_access"] = 1 radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK) @@ -122,17 +119,7 @@ obj/machinery/door/airlock/Bumped(atom/AM) if(istype(AM, /obj/mecha)) var/obj/mecha/mecha = AM if(density && radio_connection && mecha.occupant && (src.allowed(mecha.occupant) || src.check_access_list(mecha.operation_req_access))) - var/datum/signal/signal = new - signal.transmission_method = 1 //radio signal - signal.data["tag"] = id_tag - signal.data["timestamp"] = world.time - - signal.data["door_status"] = density?("closed"):("open") - signal.data["lock_status"] = locked?("locked"):("unlocked") - - signal.data["bumped_with_access"] = 1 - - radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK) + send_status(1) return obj/machinery/door/airlock/proc/set_frequency(new_frequency) @@ -258,6 +245,12 @@ obj/machinery/access_button/update_icon() else icon_state = "access_button_off" +obj/machinery/access_button/attackby(obj/item/I as obj, mob/user as mob, params) + //Swiping ID on the access button + if (istype(I, /obj/item/weapon/card/id) || istype(I, /obj/item/device/pda)) + attack_hand(user) + return + ..() obj/machinery/access_button/attack_hand(mob/user) add_fingerprint(usr) @@ -296,4 +289,4 @@ obj/machinery/access_button/airlock_interior obj/machinery/access_button/airlock_exterior frequency = 1379 - command = "cycle_exterior" + command = "cycle_exterior" \ No newline at end of file diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 88d72fbf8b9..30122e4d4b7 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -20,6 +20,7 @@ var/heat_proof = 0 // For glass airlocks/opacity firedoors var/emergency = 0 var/air_properties_vary_with_direction = 0 + var/block_air_zones = 1 //If set, air zones cannot merge across the door even when it is opened. //Multi-tile doors dir = EAST @@ -96,7 +97,7 @@ /obj/machinery/door/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group) return 0 + if(air_group) return !block_air_zones if(istype(mover) && mover.checkpass(PASSGLASS)) return !opacity return !density @@ -143,7 +144,7 @@ return ..() -/obj/machinery/door/attackby(obj/item/I as obj, mob/user as mob) +/obj/machinery/door/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/device/detective_scanner)) return if(src.operating || isrobot(user)) return //borgs can't attack doors open because it conflicts with their AI-like interaction with them. @@ -153,10 +154,7 @@ if(!src.requiresID()) user = null if(src.density && (istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade))) - flick("door_spark", src) - sleep(6) - open() - operating = -1 + emag_act(user) return 1 if(src.allowed(user) || src.emergency == 1) if(src.density) @@ -168,6 +166,13 @@ flick("door_deny", src) return +/obj/machinery/door/emag_act(user as mob) + if(density) + flick("door_spark", src) + sleep(6) + open() + operating = -1 + return 1 /obj/machinery/door/blob_act() if(prob(40)) diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index a6609c03ec1..968f5b8575e 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -60,6 +60,10 @@ opacity = 0 density = 0 + //These are frequenly used with windows, so make sure zones can pass. + //Generally if a firedoor is at a place where there should be a zone boundery then there will be a regular door underneath it. + block_air_zones = 0 + var/blocked = 0 var/lockdown = 0 // When the door has detected a problem, it locks. var/pdiff_alert = 0 @@ -106,7 +110,7 @@ /obj/machinery/door/firedoor/examine() set src in view() . = ..() - + if(pdiff >= FIREDOOR_MAX_PRESSURE_DIFF) usr << "WARNING: Current pressure differential is [pdiff]kPa! Opening door may result in injury!" @@ -169,7 +173,7 @@ /obj/machinery/door/firedoor/attack_hand(mob/user as mob) return attackby(null, user) -/obj/machinery/door/firedoor/attackby(obj/item/weapon/C as obj, mob/user as mob) +/obj/machinery/door/firedoor/attackby(obj/item/weapon/C as obj, mob/user as mob, params) add_fingerprint(user) if(operating) return//Already doing something. @@ -287,7 +291,7 @@ /obj/machinery/door/firedoor/attack_ai(mob/user as mob) if(operating) - return //Already doing something. + return //Already doing something. if(blocked) user << "\red \The [src] is welded solid!" @@ -295,11 +299,11 @@ var/area/A = get_area_master(src) ASSERT(istype(A)) // This worries me. - var/alarmed = A.air_doors_activated || A.fire + var/alarmed = A.air_doors_activated || A.fire var/access_granted = 0 if(isAI(user) || isrobot(user)) - access_granted = 1 + access_granted = 1 if(access_granted == 1) user.visible_message("\blue \The [src] [density ? "open" : "close"]s for \the [user].",\ @@ -320,7 +324,7 @@ spawn(50) if(alarmed) nextstate = CLOSED - + // CHECK PRESSURE /obj/machinery/door/firedoor/process() ..() diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm index eeceaf2de18..2495dbfc4bc 100644 --- a/code/game/machinery/doors/poddoor.dm +++ b/code/game/machinery/doors/poddoor.dm @@ -25,7 +25,7 @@ else return 0 -/obj/machinery/door/poddoor/attackby(obj/item/weapon/C as obj, mob/user as mob) +/obj/machinery/door/poddoor/attackby(obj/item/weapon/C as obj, mob/user as mob, params) src.add_fingerprint(user) if (!( istype(C, /obj/item/weapon/crowbar) || (istype(C, /obj/item/weapon/twohanded/fireaxe) && C:wielded == 1) )) return diff --git a/code/game/machinery/doors/shutters.dm b/code/game/machinery/doors/shutters.dm index 8f54535c8fe..d8f751ec89e 100644 --- a/code/game/machinery/doors/shutters.dm +++ b/code/game/machinery/doors/shutters.dm @@ -13,7 +13,7 @@ density = 0 opacity = 0 -/obj/machinery/door/poddoor/shutters/attackby(obj/item/weapon/C as obj, mob/user as mob) +/obj/machinery/door/poddoor/shutters/attackby(obj/item/weapon/C as obj, mob/user as mob, params) add_fingerprint(user) if(!(istype(C, /obj/item/weapon/crowbar) || (istype(C, /obj/item/weapon/twohanded/fireaxe) && C:wielded == 1) )) return diff --git a/code/game/machinery/doors/unpowered.dm b/code/game/machinery/doors/unpowered.dm index dce2ab37bda..8e03e874a71 100644 --- a/code/game/machinery/doors/unpowered.dm +++ b/code/game/machinery/doors/unpowered.dm @@ -10,7 +10,7 @@ return - attackby(obj/item/I as obj, mob/user as mob) + attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade)) return if(src.locked) return ..() diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 84563748126..a8ebd55930a 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -195,12 +195,15 @@ /obj/machinery/door/window/proc/attack_generic(mob/user as mob, damage = 0) if(src.operating) return + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1) user.visible_message("[user] smashes against the [src.name].", \ "[user] smashes against the [src.name].") take_damage(damage) /obj/machinery/door/window/attack_alien(mob/living/user as mob) + if(islarva(user)) return attack_generic(user, 25) @@ -225,21 +228,13 @@ /obj/machinery/door/window/attack_hand(mob/user as mob) return src.attackby(user, user) -/obj/machinery/door/window/attackby(obj/item/weapon/I as obj, mob/living/user as mob) - - //If it's in the process of opening/closing, ignore the click - if (src.operating) - return - - add_fingerprint(user) - - //Emags and ninja swords? You may pass. - if (src.density && (istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade))) +/obj/machinery/door/window/emag_act(user as mob, weapon as obj) + if(density) src.operating = -1 flick("[src.base_state]spark", src) sleep(6) desc += "
Its access panel is smoking slightly." - if(istype(I, /obj/item/weapon/melee/energy/blade)) + if(istype(weapon, /obj/item/weapon/melee/energy/blade)) var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() spark_system.set_up(5, 0, src.loc) spark_system.start() @@ -252,6 +247,19 @@ open() emagged = 1 return 1 + +/obj/machinery/door/window/attackby(obj/item/weapon/I as obj, mob/living/user as mob, params) + + //If it's in the process of opening/closing, ignore the click + if (src.operating) + return + + add_fingerprint(user) + + //Ninja swords? You may pass. + if (src.density && (istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade))) + emag_act(user,I) + return 1 if(istype(I, /obj/item/weapon/screwdriver)) if(src.density || src.operating) @@ -325,6 +333,8 @@ //If it's a weapon, smash windoor. Unless it's an id card, agent card, ect.. then ignore it (Cards really shouldnt damage a door anyway) if(src.density && istype(I, /obj/item/weapon) && !istype(I, /obj/item/weapon/card) ) + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) if( (I.flags&NOBLUDGEON) || !I.force ) return var/aforce = I.force diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm index 9866dc54502..840ed1133c2 100644 --- a/code/game/machinery/doppler_array.dm +++ b/code/game/machinery/doppler_array.dm @@ -19,7 +19,7 @@ var/list/doppler_arrays = list() /obj/machinery/doppler_array/process() return PROCESS_KILL -/obj/machinery/doppler_array/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/machinery/doppler_array/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(istype(O, /obj/item/weapon/wrench)) playsound(loc, 'sound/items/Ratchet.ogg', 50, 1) anchored = !anchored diff --git a/code/game/machinery/drying_rack.dm b/code/game/machinery/drying_rack.dm index d776fc3bef3..f8c76de25ff 100644 --- a/code/game/machinery/drying_rack.dm +++ b/code/game/machinery/drying_rack.dm @@ -31,11 +31,11 @@ -/obj/machinery/drying_rack/attackby(var/obj/item/W as obj, var/mob/user as mob) +/obj/machinery/drying_rack/attackby(var/obj/item/W as obj, var/mob/user as mob, params) if(is_type_in_list(W,accepted)) if(!running) if(istype(W,/obj/item/weapon/reagent_containers/food/snacks/meat)) - user.u_equip(W) + user.unEquip(W) del(W) user << "You add the meat to the drying rack." src.running = 1 @@ -48,7 +48,7 @@ src.running = 0 return if(istype(W,/obj/item/weapon/reagent_containers/food/snacks/grown/grapes)) - user.u_equip(W) + user.unEquip(W) del(W) user << "You add the grapes to the drying rack." src.running = 1 @@ -61,7 +61,7 @@ src.running = 0 return if(istype(W,/obj/item/weapon/reagent_containers/food/snacks/grown/greengrapes)) - user.u_equip(W) + user.unEquip(W) del(W) user << "You add the green grapes to the drying rack." src.running = 1 @@ -79,7 +79,7 @@ var/obj/item/weapon/reagent_containers/food/snacks/grown/B = W B.reagents.trans_to(src, B.reagents.total_volume) user << "You add the [W] to the drying rack." - user.u_equip(W) + user.unEquip(W) del(W) src.running = 1 use_power = 2 diff --git a/code/game/machinery/embedded_controller/airlock_controllers.dm b/code/game/machinery/embedded_controller/airlock_controllers.dm index 4a2a9c5e56e..fb909dee555 100644 --- a/code/game/machinery/embedded_controller/airlock_controllers.dm +++ b/code/game/machinery/embedded_controller/airlock_controllers.dm @@ -1,13 +1,15 @@ //base type for controllers of two-door systems /obj/machinery/embedded_controller/radio/airlock // Setup parameters only + radio_filter = RADIO_AIRLOCK var/tag_exterior_door var/tag_interior_door var/tag_airpump var/tag_chamber_sensor var/tag_exterior_sensor var/tag_interior_sensor - var/tag_mech_sensor + var/tag_airlock_mech_sensor + var/tag_shuttle_mech_sensor var/tag_secure = 0 /obj/machinery/embedded_controller/radio/airlock/initialize() diff --git a/code/game/machinery/embedded_controller/airlock_program.dm b/code/game/machinery/embedded_controller/airlock_program.dm index 90a2ca57206..8cb3abb9980 100644 --- a/code/game/machinery/embedded_controller/airlock_program.dm +++ b/code/game/machinery/embedded_controller/airlock_program.dm @@ -1,8 +1,9 @@ //Handles the control of airlocks -#define STATE_WAIT 0 -#define STATE_DEPRESSURIZE 1 -#define STATE_PRESSURIZE 2 +#define STATE_IDLE 0 +#define STATE_PREPARE 1 +#define STATE_DEPRESSURIZE 2 +#define STATE_PRESSURIZE 3 #define TARGET_NONE 0 #define TARGET_INOPEN -1 @@ -16,9 +17,10 @@ var/tag_chamber_sensor var/tag_exterior_sensor var/tag_interior_sensor - var/tag_mech_sensor + var/tag_airlock_mech_sensor + var/tag_shuttle_mech_sensor - var/state = STATE_WAIT + var/state = STATE_IDLE var/target_state = TARGET_NONE /datum/computer/file/embedded_program/airlock/New(var/obj/machinery/embedded_controller/M) @@ -42,7 +44,8 @@ tag_chamber_sensor = controller.tag_chamber_sensor? controller.tag_chamber_sensor : "[id_tag]_sensor" tag_exterior_sensor = controller.tag_exterior_sensor tag_interior_sensor = controller.tag_interior_sensor - tag_mech_sensor = controller.tag_mech_sensor? controller.tag_mech_sensor : "[id_tag]_mech" + tag_airlock_mech_sensor = controller.tag_airlock_mech_sensor? controller.tag_airlock_mech_sensor : "[id_tag]_airlock_mech" + tag_shuttle_mech_sensor = controller.tag_shuttle_mech_sensor? controller.tag_shuttle_mech_sensor : "[id_tag]_shuttle_mech" memory["secure"] = controller.tag_secure spawn(10) @@ -157,7 +160,7 @@ /datum/computer/file/embedded_program/airlock/process() - if(!state) + if(!state) //Idle if(target_state) switch(target_state) if(TARGET_INOPEN) @@ -168,38 +171,45 @@ //lock down the airlock before activating pumps close_doors() - var/chamber_pressure = memory["chamber_sensor_pressure"] - var/target_pressure = memory["target_pressure"] - - if(memory["purge"]) - target_pressure = 0 - - if(chamber_pressure <= target_pressure) - state = STATE_PRESSURIZE - signalPump(tag_airpump, 1, 1, target_pressure) //send a signal to start pressurizing - - else if(chamber_pressure > target_pressure) - state = STATE_DEPRESSURIZE - signalPump(tag_airpump, 1, 0, target_pressure) //send a signal to start depressurizing - - //Check for vacuum - this is set after the pumps so the pumps are aiming for 0 - if(!memory["target_pressure"]) - memory["target_pressure"] = ONE_ATMOSPHERE * 0.05 + state = STATE_PREPARE else //make sure to return to a sane idle state if(memory["pump_status"] != "off") //send a signal to stop pumping signalPump(tag_airpump, 0) - //the airlock will not allow itself to continue to cycle when any of the doors are forced open. - if (state && !check_doors_secured()) + if ((state == STATE_PRESSURIZE || state == STATE_DEPRESSURIZE) && !check_doors_secured()) + //the airlock will not allow itself to continue to cycle when any of the doors are forced open. stop_cycling() switch(state) + if(STATE_PREPARE) + if (check_doors_secured()) + var/chamber_pressure = memory["chamber_sensor_pressure"] + var/target_pressure = memory["target_pressure"] + + if(memory["purge"]) + target_pressure = 0 + + if(memory["purge"]) + target_pressure = 0 + + if(chamber_pressure <= target_pressure) + state = STATE_PRESSURIZE + signalPump(tag_airpump, 1, 1, target_pressure) //send a signal to start pressurizing + + else if(chamber_pressure > target_pressure) + state = STATE_DEPRESSURIZE + signalPump(tag_airpump, 1, 0, target_pressure) //send a signal to start depressurizing + + //Check for vacuum - this is set after the pumps so the pumps are aiming for 0 + if(!memory["target_pressure"]) + memory["target_pressure"] = ONE_ATMOSPHERE * 0.05 + if(STATE_PRESSURIZE) if(memory["chamber_sensor_pressure"] >= memory["target_pressure"] * 0.95) cycleDoors(target_state) - state = STATE_WAIT + state = STATE_IDLE target_state = TARGET_NONE if(memory["pump_status"] != "off") @@ -216,7 +226,7 @@ else if(memory["chamber_sensor_pressure"] <= memory["target_pressure"] * 1.05) cycleDoors(target_state) - state = STATE_WAIT + state = STATE_IDLE target_state = TARGET_NONE //send a signal to stop pumping @@ -231,11 +241,11 @@ //these are here so that other types don't have to make so many assuptions about our implementation /datum/computer/file/embedded_program/airlock/proc/begin_cycle_in() - state = STATE_WAIT + state = STATE_IDLE target_state = TARGET_INOPEN /datum/computer/file/embedded_program/airlock/proc/begin_cycle_out() - state = STATE_WAIT + state = STATE_IDLE target_state = TARGET_OUTOPEN /datum/computer/file/embedded_program/airlock/proc/close_doors() @@ -243,11 +253,11 @@ toggleDoor(memory["exterior_status"], tag_exterior_door, 1, "close") /datum/computer/file/embedded_program/airlock/proc/stop_cycling() - state = STATE_WAIT + state = STATE_IDLE target_state = TARGET_NONE /datum/computer/file/embedded_program/airlock/proc/done_cycling() - return (state == STATE_WAIT && target_state == TARGET_NONE) + return (state == STATE_IDLE && target_state == TARGET_NONE) //are the doors closed and locked? /datum/computer/file/embedded_program/airlock/proc/check_exterior_door_secured() @@ -265,7 +275,7 @@ var/datum/signal/signal = new signal.data["tag"] = tag signal.data["command"] = command - post_signal(signal) + post_signal(signal, RADIO_AIRLOCK) /datum/computer/file/embedded_program/airlock/proc/signalPump(var/tag, var/power, var/direction, var/pressure) var/datum/signal/signal = new @@ -295,11 +305,19 @@ signalDoor(tag_exterior_door, command) signalDoor(tag_interior_door, command) +datum/computer/file/embedded_program/airlock/proc/signal_mech_sensor(var/command, var/sensor) + var/datum/signal/signal = new + signal.data["tag"] = sensor + signal.data["command"] = command + post_signal(signal) + /datum/computer/file/embedded_program/airlock/proc/enable_mech_regulation() - signalDoor(tag_mech_sensor, "enable") + signal_mech_sensor("enable", tag_shuttle_mech_sensor) + signal_mech_sensor("enable", tag_airlock_mech_sensor) /datum/computer/file/embedded_program/airlock/proc/disable_mech_regulation() - signalDoor(tag_mech_sensor, "disable") + signal_mech_sensor("disable", tag_shuttle_mech_sensor) + signal_mech_sensor("disable", tag_airlock_mech_sensor) /*---------------------------------------------------------- toggleDoor() @@ -355,7 +373,7 @@ send an additional command to open the door again. signalDoor(doorTag, doorCommand) -#undef STATE_WAIT +#undef STATE_IDLE #undef STATE_DEPRESSURIZE #undef STATE_PRESSURIZE diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm index a9a8b40ed58..ec411753803 100644 --- a/code/game/machinery/embedded_controller/embedded_controller_base.dm +++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm @@ -3,6 +3,9 @@ name = "Embedded Controller" anchored = 1 + + use_power = 1 + idle_power_usage = 10 var/on = 1 @@ -43,8 +46,10 @@ density = 0 var/id_tag + //var/radio_power_use = 50 //power used to xmit signals var/frequency = 1379 + var/radio_filter = null var/datum/radio_frequency/radio_connection unacidable = 1 @@ -60,14 +65,15 @@ else icon_state = "airlock_control_off" -/obj/machinery/embedded_controller/radio/post_signal(datum/signal/signal) +/obj/machinery/embedded_controller/radio/post_signal(datum/signal/signal, var/filter = null) signal.transmission_method = TRANSMISSION_RADIO if(radio_connection) - return radio_connection.post_signal(src, signal) + //use_power(radio_power_use) //neat idea, but causes way too much lag. + return radio_connection.post_signal(src, signal, filter) else del(signal) /obj/machinery/embedded_controller/radio/proc/set_frequency(new_frequency) radio_controller.remove_object(src, frequency) frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency) \ No newline at end of file + radio_connection = radio_controller.add_object(src, frequency, radio_filter) \ No newline at end of file diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index d51f29655de..148e1b53322 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -38,7 +38,7 @@ // src.sd_SetLuminosity(0) //Don't want to render prison breaks impossible -/obj/machinery/flasher/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/flasher/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/wirecutters)) add_fingerprint(user) src.disable = !src.disable @@ -107,7 +107,7 @@ if ((M.m_intent != "walk") && (src.anchored)) src.flash() -/obj/machinery/flasher/portable/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/flasher/portable/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/wrench)) add_fingerprint(user) src.anchored = !src.anchored @@ -126,7 +126,7 @@ /obj/machinery/flasher_button/attack_paw(mob/user as mob) return src.attack_hand(user) -/obj/machinery/flasher_button/attackby(obj/item/weapon/W, mob/user as mob) +/obj/machinery/flasher_button/attackby(obj/item/weapon/W, mob/user as mob, params) return src.attack_hand(user) /obj/machinery/flasher_button/attack_hand(mob/user as mob) diff --git a/code/game/machinery/floodlight.dm b/code/game/machinery/floodlight.dm index b7203be245d..b6da9e11d95 100644 --- a/code/game/machinery/floodlight.dm +++ b/code/game/machinery/floodlight.dm @@ -4,9 +4,10 @@ name = "Emergency Floodlight" icon = 'icons/obj/machines/floodlight.dmi' icon_state = "flood00" + anchored = 0 density = 1 var/on = 0 - var/obj/item/weapon/cell/high/cell = null + var/obj/item/weapon/stock_parts/cell/high/cell = null var/use = 5 var/unlocked = 0 var/open = 0 @@ -62,7 +63,22 @@ updateicon() -/obj/machinery/floodlight/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/floodlight/attackby(obj/item/weapon/W as obj, mob/user as mob, params) + if(istype(W, /obj/item/weapon/wrench)) + if (!anchored && !isinspace()) + playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) + user.visible_message( \ + "[user] tightens \the [src]'s casters.", \ + " You have tightened \the [src]'s casters.", \ + "You hear ratchet.") + anchored = 1 + else if(anchored) + playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) + user.visible_message( \ + "[user] loosens \the [src]'s casters.", \ + " You have loosened \the [src]'s casters.", \ + "You hear ratchet.") + anchored = 0 if (istype(W, /obj/item/weapon/screwdriver)) if (!open) if(unlocked) @@ -83,7 +99,7 @@ open = 1 user << "You remove the battery panel." - if (istype(W, /obj/item/weapon/cell)) + if (istype(W, /obj/item/weapon/stock_parts/cell)) if(open) if(cell) user << "There is a power cell already installed." diff --git a/code/game/machinery/guestpass.dm b/code/game/machinery/guestpass.dm index ee93ac74799..83cf1682bd8 100644 --- a/code/game/machinery/guestpass.dm +++ b/code/game/machinery/guestpass.dm @@ -54,7 +54,7 @@ var/list/internal_log = list() var/mode = 0 // 0 - making pass, 1 - viewing logs -/obj/machinery/computer/guestpass/attackby(obj/O, mob/user) +/obj/machinery/computer/guestpass/attackby(obj/O, mob/user, params) if(istype(O, /obj/item/weapon/card/id)) if(!giver) user.drop_item() @@ -105,7 +105,7 @@ /obj/machinery/computer/guestpass/Topic(href, href_list) if(..()) - return + return 1 usr.set_machine(src) if (href_list["mode"]) mode = text2num(href_list["mode"]) diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index 265145b4a04..a04ed3f2053 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -81,13 +81,20 @@ 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, verb) +/obj/machinery/hologram/holopad/hear_talk(mob/living/M, text, verb, datum/language/speaking) 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) + if(!master.say_understands(M, speaking))//The AI will be able to understand most mobs talking through the holopad. + if(speaking) + text = speaking.scramble(text) + else + 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] [verb], \"[text]\"" + var/rendered + if(speaking) + rendered = "Holopad received, [name_used] [speaking.format_message(text, verb)]" + else + rendered = "Holopad received, [name_used] [verb], \"[text]\"" master.show_message(rendered, 2) return diff --git a/code/game/machinery/holosign.dm b/code/game/machinery/holosign.dm index 073973cdee7..cd1e5a85e62 100644 --- a/code/game/machinery/holosign.dm +++ b/code/game/machinery/holosign.dm @@ -50,7 +50,7 @@ obj/machinery/holosign_switch/attack_paw(mob/user as mob) return src.attack_hand(user) -/obj/machinery/holosign_switch/attackby(obj/item/weapon/W, mob/user as mob) +/obj/machinery/holosign_switch/attackby(obj/item/weapon/W, mob/user as mob, params) if(istype(W, /obj/item/device/detective_scanner)) return return src.attack_hand(user) diff --git a/code/game/machinery/hydroponics.dm b/code/game/machinery/hydroponics.dm index 58d52bc992b..ef9a7d29150 100644 --- a/code/game/machinery/hydroponics.dm +++ b/code/game/machinery/hydroponics.dm @@ -664,7 +664,7 @@ return -/obj/machinery/portable_atmospherics/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/machinery/portable_atmospherics/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(exchange_parts(user, O)) return @@ -958,7 +958,7 @@ use_power = 0 draw_warnings = 0 -/obj/machinery/portable_atmospherics/hydroponics/soil/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/machinery/portable_atmospherics/hydroponics/soil/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(istype(O, /obj/item/weapon/shovel)) user << "You clear up [src]!" del(src) diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm index 7aba3dc25f1..9577a539203 100755 --- a/code/game/machinery/igniter.dm +++ b/code/game/machinery/igniter.dm @@ -71,7 +71,7 @@ icon_state = "[base_state]-p" // src.sd_SetLuminosity(0) -/obj/machinery/sparker/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/sparker/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/device/detective_scanner)) return if (istype(W, /obj/item/weapon/screwdriver)) @@ -125,7 +125,7 @@ /obj/machinery/ignition_switch/attack_paw(mob/user as mob) return src.attack_hand(user) -/obj/machinery/ignition_switch/attackby(obj/item/weapon/W, mob/user as mob) +/obj/machinery/ignition_switch/attackby(obj/item/weapon/W, mob/user as mob, params) return src.attack_hand(user) /obj/machinery/ignition_switch/attack_hand(mob/user as mob) diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index 17127b65378..31b41770259 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -37,6 +37,13 @@ /obj/machinery/iv_drip/MouseDrop(over_object, src_location, over_location) ..() + + if(!ishuman(usr) && !isrobot(usr)) + return + + var/turf/T = get_turf(src) + if(!usr in range(1, T)) + return if(attached) visible_message("[src.attached] is detached from \the [src]") @@ -50,7 +57,7 @@ src.update_icon() -/obj/machinery/iv_drip/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/iv_drip/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/reagent_containers)) if(!isnull(src.beaker)) user << "There is already a reagent container loaded!" @@ -103,7 +110,7 @@ if(!istype(T)) return if(!T.dna) return - if(M_NOCLONE in T.mutations) + if(NOCLONE in T.mutations) return if(T.species && T.species.flags & NO_BLOOD) @@ -133,6 +140,7 @@ /obj/machinery/iv_drip/verb/toggle_mode() set name = "Toggle Mode" + set category = "Object" set src in view(1) if(!istype(usr, /mob/living)) diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm index d5510dbbd26..8e657b6b53f 100644 --- a/code/game/machinery/kitchen/gibber.dm +++ b/code/game/machinery/kitchen/gibber.dm @@ -78,7 +78,7 @@ else src.startgibbing(user) -/obj/machinery/gibber/attackby(obj/item/weapon/grab/G as obj, mob/user as mob) +/obj/machinery/gibber/attackby(obj/item/weapon/grab/G as obj, mob/user as mob, params) if(src.occupant) user << "\red The gibber is full, empty it first!" return diff --git a/code/game/machinery/kitchen/icecream_vat.dm b/code/game/machinery/kitchen/icecream_vat.dm index ab39761b3da..711e2020361 100644 --- a/code/game/machinery/kitchen/icecream_vat.dm +++ b/code/game/machinery/kitchen/icecream_vat.dm @@ -89,7 +89,7 @@ var/list/ingredients_source = list( user << browse(dat,"window=icecreamvat;size=600x400") -/obj/machinery/icecream_vat/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/machinery/icecream_vat/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(istype(O, /obj/item/weapon/reagent_containers)) if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/icecream)) var/obj/item/weapon/reagent_containers/food/snacks/icecream/I = O diff --git a/code/game/machinery/kitchen/juicer.dm b/code/game/machinery/kitchen/juicer.dm index b237f8223f6..86d59679f76 100644 --- a/code/game/machinery/kitchen/juicer.dm +++ b/code/game/machinery/kitchen/juicer.dm @@ -31,13 +31,15 @@ return -/obj/machinery/juicer/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/machinery/juicer/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if (istype(O,/obj/item/weapon/reagent_containers/glass) || \ istype(O,/obj/item/weapon/reagent_containers/food/drinks/drinkingglass)) if (beaker) return 1 else - user.before_take_item(O) + if(!user.unEquip(O)) + user << "\the [O] is stuck to your hand, you cannot put it in \the [src]" + return 0 O.loc = src beaker = O src.verbs += /obj/machinery/juicer/verb/detach @@ -45,9 +47,11 @@ src.updateUsrDialog() return 0 if (!is_type_in_list(O, allowed_items)) - user << "It looks as not containing any juice." + user << "It doesn't look like that contains any juice." return 1 - user.before_take_item(O) + if(!user.unEquip(O)) + user << "\the [O] is stuck to your hand, you cannot put it in \the [src]" + return 0 O.loc = src src.updateUsrDialog() return 0 diff --git a/code/game/machinery/kitchen/microwave.dm b/code/game/machinery/kitchen/microwave.dm index 0268755bb1a..cd8e806fbb0 100644 --- a/code/game/machinery/kitchen/microwave.dm +++ b/code/game/machinery/kitchen/microwave.dm @@ -49,7 +49,7 @@ component_parts += new /obj/item/weapon/stock_parts/micro_laser(null) component_parts += new /obj/item/weapon/stock_parts/console_screen(null) component_parts += new /obj/item/stack/cable_coil(null, 2) - RefreshParts() + RefreshParts() /obj/machinery/microwave/upgraded/New() @@ -59,19 +59,19 @@ component_parts += new /obj/item/weapon/stock_parts/micro_laser/ultra(null) component_parts += new /obj/item/weapon/stock_parts/console_screen(null) component_parts += new /obj/item/stack/cable_coil(null, 2) - RefreshParts() + RefreshParts() /obj/machinery/microwave/RefreshParts() var/E for(var/obj/item/weapon/stock_parts/micro_laser/M in component_parts) E += M.rating - efficiency = E - + efficiency = E + /******************* * Item Adding ********************/ -/obj/machinery/microwave/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/machinery/microwave/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(operating) return if(!broken && dirty < 100) @@ -87,11 +87,11 @@ return else if(!anchored) anchored = 1 - user << "The [src] is now secured." + user << "The [src] is now secured." return - + default_deconstruction_crowbar(O) - + if(src.broken > 0) if(src.broken == 2 && istype(O, /obj/item/weapon/screwdriver)) // If it's broken and they're using a screwdriver user.visible_message( \ @@ -150,8 +150,10 @@ "\blue [user] has added one of [O] to \the [src].", \ "\blue You add one of [O] to \the [src].") else - // user.before_take_item(O) //This just causes problems so far as I can tell. -Pete - user.drop_item() + // user.unEquip(O) //This just causes problems so far as I can tell. -Pete + if(!user.drop_item()) + user << "\the [O] is stuck to your hand, you cannot put it in \the [src]" + return 0 O.loc = src user.visible_message( \ "\blue [user] has added \the [O] to \the [src].", \ diff --git a/code/game/machinery/kitchen/monkeyrecycler.dm b/code/game/machinery/kitchen/monkeyrecycler.dm index f4b373e8eab..9342e6530b3 100644 --- a/code/game/machinery/kitchen/monkeyrecycler.dm +++ b/code/game/machinery/kitchen/monkeyrecycler.dm @@ -12,7 +12,7 @@ var/grinded = 0 -/obj/machinery/monkey_recycler/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/machinery/monkey_recycler/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if (src.stat != 0) //NOPOWER etc return if (istype(O, /obj/item/weapon/grab)) diff --git a/code/game/machinery/kitchen/processor.dm b/code/game/machinery/kitchen/processor.dm index aea4592faae..f466149d8d1 100644 --- a/code/game/machinery/kitchen/processor.dm +++ b/code/game/machinery/kitchen/processor.dm @@ -104,7 +104,7 @@ return P return 0 -/obj/machinery/processor/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/machinery/processor/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(src.processing) user << "\red The processor is in the process of processing." return 1 diff --git a/code/game/machinery/kitchen/smartfridge.dm b/code/game/machinery/kitchen/smartfridge.dm index 7f8ba253582..397ee26b20a 100644 --- a/code/game/machinery/kitchen/smartfridge.dm +++ b/code/game/machinery/kitchen/smartfridge.dm @@ -75,7 +75,7 @@ * Item Adding ********************/ -/obj/machinery/smartfridge/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/machinery/smartfridge/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(!src.ispowered) user << "\The [src] is unpowered and useless." return @@ -85,7 +85,9 @@ user << "\The [src] is full." return 1 else - user.before_take_item(O) + if(!user.unEquip(O)) + usr << "\the [O] is stuck to your hand, you cannot put it in \the [src]" + return O.loc = src if(item_quants[O.name]) item_quants[O.name]++ diff --git a/code/game/machinery/laprecharger.dm b/code/game/machinery/laprecharger.dm new file mode 100644 index 00000000000..cafd5e3d297 --- /dev/null +++ b/code/game/machinery/laprecharger.dm @@ -0,0 +1,101 @@ +//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 + +/obj/machinery/laprecharger + name = "laptop recharger" + icon = 'icons/obj/stationobjs.dmi' + icon_state = "recharger0" + anchored = 1 + use_power = 1 + idle_power_usage = 40 + active_power_usage = 2500 + var/obj/item/charging = null + var/icon_state_charged = "recharger2" + var/icon_state_charging = "recharger1" + var/icon_state_idle = "recharger0" + +/obj/machinery/laprecharger/attackby(obj/item/weapon/G as obj, mob/user as mob, params) + if(istype(user,/mob/living/silicon)) + return + if(istype(G, /obj/item/weapon/gun/energy) || istype(G, /obj/item/weapon/melee/baton)) + user << "\red The laptop recharger blinks red as you try to insert the item!" + return + if(istype(G,/obj/item/device/laptop)) + if(charging) + return + + + // Checks to make sure he's not in space doing it, and that the area got proper power. + var/area/a = get_area(src) + if(!isarea(a)) + user << "\red The [name] blinks red as you try to insert the item!" + return + if(a.power_equip == 0) + user << "\red The [name] blinks red as you try to insert the item!" + return + + if(istype(G, /obj/item/device/laptop)) + var/obj/item/device/laptop/L = G + if(!L.stored_computer.battery) + user << "There's no battery in it!" + return + user.drop_item() + G.loc = src + charging = G + use_power = 2 + update_icon() + else if(istype(G, /obj/item/weapon/wrench)) + if(charging) + user << "\red Remove the laptop first!" + return + anchored = !anchored + user << "You [anchored ? "attached" : "detached"] the recharger." + playsound(loc, 'sound/items/Ratchet.ogg', 75, 1) + +/obj/machinery/laprecharger/attack_hand(mob/user as mob) + add_fingerprint(user) + + if(charging) + charging.update_icon() + charging.loc = loc + charging = null + use_power = 1 + update_icon() + +/obj/machinery/laprecharger/attack_paw(mob/user as mob) + return attack_hand(user) + +/obj/machinery/laprecharger/process() + if(stat & (NOPOWER|BROKEN) || !anchored) + return + + if(charging) + if(istype(charging, /obj/item/device/laptop)) + var/obj/item/device/laptop/L = charging + if(L.stored_computer.battery.charge < L.stored_computer.battery.maxcharge) + L.stored_computer.battery.give(1000) + icon_state = icon_state_charging + use_power(2500) + else + icon_state = icon_state_charged + return + + +/obj/machinery/laprecharger/emp_act(severity) + if(stat & (NOPOWER|BROKEN) || !anchored) + ..(severity) + return + +/obj/machinery/laprecharger/update_icon() //we have an update_icon() in addition to the stuff in process to make it feel a tiny bit snappier. + if(charging) + icon_state = icon_state_charging + else + icon_state = icon_state_idle + +// Atlantis: No need for that copy-pasta code, just use var to store icon_states instead. +obj/machinery/laprecharger/wallcharger + name = "wall laptop recharger" + icon = 'icons/obj/stationobjs.dmi' + icon_state = "wrecharger0" + icon_state_idle = "wrecharger0" + icon_state_charging = "wrecharger1" + icon_state_charged = "wrecharger2" diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 5e69e5701af..6a0bcbf496f 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -184,37 +184,21 @@ Class Procs: use_power(active_power_usage,power_channel, 1) return 1 -/obj/machinery/Topic(href, href_list) +/obj/machinery/CanUseTopic(var/mob/user, var/be_close) + if(!interact_offline && (stat & (NOPOWER|BROKEN))) + return STATUS_CLOSE + + return ..() + +/obj/machinery/CouldUseTopic(var/mob/user) ..() - if(!interact_offline && stat & (NOPOWER|BROKEN)) - return 1 - if(usr.restrained() || usr.lying || usr.stat) - 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") ) - usr << "\red You don't have the dexterity to do this!" - return 1 + user.set_machine(src) - var/norange = 0 - if(istype(usr, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = usr - if(istype(H.l_hand, /obj/item/tk_grab)) - norange = 1 - else if(istype(H.r_hand, /obj/item/tk_grab)) - norange = 1 - - if(!norange) - if ((!in_range(src, usr) || !istype(src.loc, /turf)) && !istype(usr, /mob/living/silicon)) - return 1 - - src.add_fingerprint(usr) - - var/area/A = get_area(src) - A.powerupdate = 1 - - return 0 +/obj/machinery/CouldNotUseTopic(var/mob/user) + usr.unset_machine() +//////////////////////////////////////////////////////////////////////////////////////////// + /obj/machinery/attack_ai(var/mob/user as mob) if(isAI(user)) var/mob/living/silicon/ai/A = user @@ -351,22 +335,6 @@ Class Procs: user << "[A.name] replaced with [B.name]." shouldplaysound = 1 break - // Power cell snowflake - for(var/obj/item/weapon/cell/A in component_parts) - for(var/D in CB.req_components) - if(ispath(A.type, D)) - P = D - break - for(var/obj/item/weapon/cell/B in W.contents) - if(istype(B, P) && istype(A, P)) - if(B.rating > A.rating) - W.remove_from_storage(B, src) - W.handle_item_insertion(A, 1) - component_parts -= A - component_parts += B - B.loc = null - user << "[A.name] replaced with [B.name]." - break RefreshParts() else user << "Following parts detected in the machine:" @@ -389,3 +357,51 @@ Class Procs: I.loc = loc del(src) return 1 + +/obj/machinery/proc/on_assess_perp(mob/living/carbon/human/perp) + return 0 + +/obj/machinery/proc/is_assess_emagged() + return emagged + +/obj/machinery/proc/assess_perp(mob/living/carbon/human/perp, var/auth_weapons, var/check_records, var/check_arrest) + var/threatcount = 0 //the integer returned + + if(is_assess_emagged()) + return 10 //if emagged, always return 10. + + threatcount += on_assess_perp(perp) + if(threatcount >= 10) + return threatcount + + //Agent cards lower threatlevel. + var/obj/item/weapon/card/id/id = GetIdCard(perp) + if(id && istype(id, /obj/item/weapon/card/id/syndicate)) + threatcount -= 2 + + if(auth_weapons && !src.allowed(perp)) + if(istype(perp.l_hand, /obj/item/weapon/gun) || istype(perp.l_hand, /obj/item/weapon/melee)) + threatcount += 4 + + if(istype(perp.r_hand, /obj/item/weapon/gun) || istype(perp.r_hand, /obj/item/weapon/melee)) + threatcount += 4 + + if(istype(perp.belt, /obj/item/weapon/gun) || istype(perp.belt, /obj/item/weapon/melee)) + threatcount += 2 + + if(perp.species.name != "Human") //beepsky so racist. + threatcount += 2 + + if(check_records || check_arrest) + var/perpname = perp.name + if(id) + perpname = id.registered_name + + var/datum/data/record/R = find_security_record("name", perpname) + if(check_records && !R) + threatcount += 4 + + if(check_arrest && R && (R.fields["criminal"] == "*Arrest*")) + threatcount += 4 + + return threatcount diff --git a/code/game/machinery/magnet.dm b/code/game/machinery/magnet.dm index a2dd432d991..8569ede3fd7 100644 --- a/code/game/machinery/magnet.dm +++ b/code/game/machinery/magnet.dm @@ -323,7 +323,7 @@ if(speed <= 0) speed = 1 if("setpath") - var/newpath = copytext(sanitize(input(usr, "Please define a new path!",,path) as text|null),1,MAX_MESSAGE_LEN) + var/newpath = sanitize(copytext(input(usr, "Please define a new path!",,path) as text|null,1,MAX_MESSAGE_LEN)) if(newpath && newpath != "") moving = 0 // stop moving path = newpath diff --git a/code/game/machinery/metaldetector.dm b/code/game/machinery/metaldetector.dm index 3d7ccb4ab3b..95e76eaa2c5 100644 --- a/code/game/machinery/metaldetector.dm +++ b/code/game/machinery/metaldetector.dm @@ -26,12 +26,7 @@ return 0 return 1 -/obj/machinery/metaldetector/attackby(obj/item/W as obj, mob/user as mob) - if(istype(W, /obj/item/weapon/card/emag)) - if(!src.emagged) - src.emagged = 1 - user << "\blue You short out the circuitry." - return +/obj/machinery/metaldetector/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/card)) for(var/ID in list(user.equipped(), user:wear_id, user:belt)) if(src.check_access(ID,list("20"))) @@ -46,6 +41,12 @@ else user << "\red You lack access to the control panel!" return + +/obj/machinery/metaldetector/emag_act(user as mob) + if(!emagged) + emagged = 1 + user << "\blue You short out the circuitry." + return /obj/machinery/metaldetector/Crossed(AM as mob|obj) if(emagged) diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm index 59bf0f2ea17..a8f39a4597e 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -101,7 +101,7 @@ frequency.post_signal(src, signal, filter = RADIO_NAVBEACONS) -/obj/machinery/navbeacon/attackby(var/obj/item/I, var/mob/user) +/obj/machinery/navbeacon/attackby(var/obj/item/I, var/mob/user, params) var/turf/T = loc if(T.intact) return // prevent intraction when T-scanner revealed @@ -193,7 +193,7 @@ Transponder Codes:
    "} updateDialog() else if(href_list["locedit"]) - var/newloc = copytext(sanitize(input("Enter New Location", "Navigation Beacon", location) as text|null),1,MAX_MESSAGE_LEN) + var/newloc = sanitize(copytext(input("Enter New Location", "Navigation Beacon", location) as text|null,1,MAX_MESSAGE_LEN)) if(newloc) location = newloc updateDialog() diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index fcb2412c122..248908ed824 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -5,6 +5,7 @@ /datum/feed_message var/author ="" var/body ="" + var/message_type ="Story" //var/parent_channel var/backup_body ="" var/backup_author ="" @@ -39,6 +40,12 @@ src.backup_author = "" src.censored = 0 src.is_admin_channel = 0 + +/datum/feed_channel/proc/announce_news() + return "Breaking news from [channel_name]!" + +/datum/feed_channel/station/announce_news() + return "New Station Announcement Available" /datum/feed_network var/list/datum/feed_channel/network_channels = list() @@ -213,7 +220,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co switch(screen) if(0) dat += {"Welcome to Newscasting Unit #[src.unit_no].
    Interface & News networks Operational. -
    Property of Nanotransen Inc"} +
    Property of Nanotrasen"} if(news_network.wanted_issue) dat+= "
    Read Wanted Issue" dat+= {"

    Create Feed Channel @@ -248,7 +255,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co dat+="No feed messages found in channel...

    " else for(var/datum/feed_message/MESSAGE in CHANNEL.messages) - dat+="-[MESSAGE.body]
    \[Story by [MESSAGE.author]\]
    "*/ + dat+="-[MESSAGE.body]
    \[[MESSAGE.message_type] by [MESSAGE.author]\]
    "*/ dat+="

    Refresh" dat+="
    Back" @@ -334,7 +341,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co if(MESSAGE.img) usr << browse_rsc(MESSAGE.img, "tmp_photo[i].png") dat+="

    " - dat+="\[Story by [MESSAGE.author]\]
    " + dat+="\[[MESSAGE.message_type] by [MESSAGE.author]\]
    " dat+="

    Refresh" dat+="
    Back" if(10) @@ -369,7 +376,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co dat+="No feed messages found in channel...
    " else for(var/datum/feed_message/MESSAGE in src.viewing_channel.messages) - dat+="-[MESSAGE.body]
    \[Story by [MESSAGE.author]\]
    " + dat+="-[MESSAGE.body]
    \[[MESSAGE.message_type] by [MESSAGE.author]\]
    " dat+="[(MESSAGE.body == "\[REDACTED\]") ? ("Undo story censorship") : ("Censor story")] - [(MESSAGE.author == "\[REDACTED\]") ? ("Undo Author Censorship") : ("Censor message Author")]
    " dat+="
    Back" if(13) @@ -383,7 +390,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co dat+="No feed messages found in channel...
    " else for(var/datum/feed_message/MESSAGE in src.viewing_channel.messages) - dat+="-[MESSAGE.body]
    \[Story by [MESSAGE.author]\]
    " + dat+="-[MESSAGE.body]
    \[[MESSAGE.message_type] by [MESSAGE.author]\]
    " dat+="
    Back" if(14) @@ -460,7 +467,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co /obj/machinery/newscaster/Topic(href, href_list) if(..()) - return + return 1 if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) usr.set_machine(src) if(href_list["set_channel_name"]) @@ -516,7 +523,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co src.updateUsrDialog() else if(href_list["set_new_message"]) - src.msg = strip_html(input(usr, "Write your Feed story", "Network Channel Handler", "")) + src.msg = strip_html(input(usr, "Write your feed story", "Network Channel Handler", "")) while (findtext(src.msg," ") == 1) src.msg = copytext(src.msg,2,lentext(src.msg)+1) src.updateUsrDialog() @@ -535,13 +542,15 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co if(photo) newMsg.img = photo.img feedback_inc("newscaster_stories",1) + var/announcement = "" for(var/datum/feed_channel/FC in news_network.network_channels) if(FC.channel_name == src.channel_name) FC.messages += newMsg //Adding message to the network's appropriate feed_channel + announcement = FC.announce_news() break src.screen=4 for(var/obj/machinery/newscaster/NEWSCASTER in allCasters) - NEWSCASTER.newsAlert(src.channel_name) + NEWSCASTER.newsAlert(announcement) src.updateUsrDialog() @@ -727,7 +736,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co src.updateUsrDialog() -/obj/machinery/newscaster/attackby(obj/item/I as obj, mob/user as mob) +/obj/machinery/newscaster/attackby(obj/item/I as obj, mob/living/user as mob, params) if(istype(I, /obj/item/weapon/wrench)) user << "Now [anchored ? "un" : ""]securing [name]" playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) @@ -929,13 +938,13 @@ obj/item/weapon/newspaper/Topic(href, href_list) src.attack_self(src.loc) -obj/item/weapon/newspaper/attackby(obj/item/weapon/W as obj, mob/user as mob) +obj/item/weapon/newspaper/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/pen)) if(src.scribble_page == src.curr_page) user << "There's already a scribble in this page... You wouldn't want to make things too cluttered, would you?" else var/s = strip_html( input(user, "Write something", "Newspaper", "") ) - s = copytext(sanitize(s), 1, MAX_MESSAGE_LEN) + s = sanitize(copytext(s, 1, MAX_MESSAGE_LEN)) if (!s) return if (!in_range(src, usr) && src.loc != usr) @@ -986,11 +995,11 @@ obj/item/weapon/newspaper/attackby(obj/item/weapon/W as obj, mob/user as mob) ///obj/machinery/newscaster/process() //Was thinking of doing the icon update through process, but multiple iterations per second does not // return //bode well with a newscaster network of 10+ machines. Let's just return it, as it's added in the machines list. -/obj/machinery/newscaster/proc/newsAlert(channel) //This isn't Agouri's work, for it is ugly and vile. +/obj/machinery/newscaster/proc/newsAlert(var/news_call) //This isn't Agouri's work, for it is ugly and vile. var/turf/T = get_turf(src) //Who the fuck uses spawn(600) anyway, jesus christ - if(channel) + if(news_call) for(var/mob/O in hearers(world.view-1, T)) - O.show_message("[src.name] beeps, \"Breaking news from [channel]!\"",2) + O.show_message("[src.name] beeps, \"[news_call]\"",2) src.alert = 1 src.update_icon() spawn(300) diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index c1cbc65c297..21e66517422 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -56,7 +56,6 @@ Buildable meters icon = 'icons/obj/pipe-item.dmi' icon_state = "simple" item_state = "buildpipe" - flags = TABLEPASS|FPRINT w_class = 3 level = 2 @@ -389,7 +388,7 @@ Buildable meters /obj/item/pipe/attack_self(mob/user as mob) return rotate() -/obj/item/pipe/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) +/obj/item/pipe/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params) ..() //* if (!istype(W, /obj/item/weapon/wrench)) @@ -432,7 +431,7 @@ Buildable meters if (P.node2) P.node2.initialize() P.node2.build_network() - + if(PIPE_SUPPLY_STRAIGHT, PIPE_SUPPLY_BENT) var/obj/machinery/atmospherics/pipe/simple/hidden/supply/P = new( src.loc ) P.color = color @@ -546,7 +545,7 @@ Buildable meters if (M.node3) M.node3.initialize() M.node3.build_network() - + if(PIPE_SUPPLY_MANIFOLD) //manifold var/obj/machinery/atmospherics/pipe/manifold/hidden/supply/M = new( src.loc ) M.color = color @@ -618,7 +617,7 @@ Buildable meters if (M.node4) M.node4.initialize() M.node4.build_network() - + if(PIPE_SUPPLY_MANIFOLD4W) //4-way manifold var/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply/M = new( src.loc ) M.color = color @@ -904,7 +903,7 @@ Buildable meters if(C.node) C.node.initialize() C.node.build_network() - + if(PIPE_SUPPLY_CAP) var/obj/machinery/atmospherics/pipe/cap/hidden/supply/C = new(src.loc) C.dir = dir @@ -1039,10 +1038,9 @@ Buildable meters icon = 'icons/obj/pipe-item.dmi' icon_state = "meter" item_state = "buildpipe" - flags = TABLEPASS|FPRINT w_class = 4 -/obj/item/pipe_meter/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) +/obj/item/pipe_meter/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob, params) ..() if (!istype(W, /obj/item/weapon/wrench)) diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm index e52737efd8f..959df353b38 100644 --- a/code/game/machinery/pipe/pipe_dispenser.dm +++ b/code/game/machinery/pipe/pipe_dispenser.dm @@ -87,7 +87,7 @@ wait = 0 return -/obj/machinery/pipedispenser/attackby(var/obj/item/W as obj, var/mob/user as mob) +/obj/machinery/pipedispenser/attackby(var/obj/item/W as obj, var/mob/user as mob, params) src.add_fingerprint(usr) if (istype(W, /obj/item/pipe) || istype(W, /obj/item/pipe_meter)) usr << "\blue You put [W] back to [src]." diff --git a/code/game/machinery/podmen.dm b/code/game/machinery/podmen.dm index 4a698e2a4e2..58dc6dc7888 100644 --- a/code/game/machinery/podmen.dm +++ b/code/game/machinery/podmen.dm @@ -27,7 +27,7 @@ Growing it to term with nothing injected will grab a ghost from the observers. * var/found_player = 0 var/beingharvested = 0 -/obj/item/seeds/replicapod/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/seeds/replicapod/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/reagent_containers)) diff --git a/code/game/machinery/portable_tag_turret.dm b/code/game/machinery/portable_tag_turret.dm new file mode 100644 index 00000000000..c6da942645a --- /dev/null +++ b/code/game/machinery/portable_tag_turret.dm @@ -0,0 +1,124 @@ +#define TURRET_PRIORITY_TARGET 2 +#define TURRET_SECONDARY_TARGET 1 +#define TURRET_NOT_TARGET 0 + +/obj/machinery/porta_turret/tag + // Reasonable defaults, in case someone manually spawns us + var/lasercolor = "r" //Something to do with lasertag turrets, blame Sieve for not adding a comment. + installation = /obj/item/weapon/gun/energy/laser/redtag + +/obj/machinery/porta_turret/tag/red + +/obj/machinery/porta_turret/tag/blue + lasercolor = "b" + installation = /obj/item/weapon/gun/energy/laser/bluetag + +/obj/machinery/porta_turret/tag/New() + ..() + icon_state = "[lasercolor]grey_target_prism" + +/obj/machinery/porta_turret/tag/weapon_setup(var/obj/item/weapon/gun/energy/E) + switch(E.type) + if(/obj/item/weapon/gun/energy/laser/bluetag) + eprojectile = /obj/item/weapon/gun/energy/laser/bluetag + lasercolor = "b" + req_access = list(access_maint_tunnels, access_theatre) + check_arrest = 0 + check_records = 0 + check_weapons = 1 + check_access = 0 + check_anomalies = 0 + shot_delay = 30 + + if(/obj/item/weapon/gun/energy/laser/redtag) + eprojectile = /obj/item/weapon/gun/energy/laser/redtag + lasercolor = "r" + req_access = list(access_maint_tunnels, access_theatre) + check_arrest = 0 + check_records = 0 + check_weapons = 1 + check_access = 0 + check_anomalies = 0 + shot_delay = 30 + iconholder = 1 + +/obj/machinery/porta_turret/tag/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] + data["access"] = !isLocked(user) + data["locked"] = locked + data["enabled"] = enabled + data["is_lethal"] = 0 + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "turret_control.tmpl", "Turret Controls", 500, 300) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + +/obj/machinery/porta_turret/tag/update_icon() + if(!anchored) + icon_state = "turretCover" + return + if(stat & BROKEN) + icon_state = "[lasercolor]destroyed_target_prism" + else + if(powered()) + if(enabled) + if(iconholder) + //lasers have a orange icon + icon_state = "[lasercolor]orange_target_prism" + else + //almost everything has a blue icon + icon_state = "[lasercolor]target_prism" + else + icon_state = "[lasercolor]grey_target_prism" + else + icon_state = "[lasercolor]grey_target_prism" + +/obj/machinery/porta_turret/tag/bullet_act(obj/item/projectile/Proj) + ..() + + if(lasercolor == "b" && disabled == 0) + if(istype(Proj, /obj/item/weapon/gun/energy/laser/redtag)) + disabled = 1 + del(Proj) // qdel + sleep(100) + disabled = 0 + if(lasercolor == "r" && disabled == 0) + if(istype(Proj, /obj/item/weapon/gun/energy/laser/bluetag)) + disabled = 1 + del(Proj) // qdel + sleep(100) + disabled = 0 + +/obj/machinery/porta_turret/tag/assess_living(var/mob/living/L) + if(!L) + return TURRET_NOT_TARGET + + if(L.lying) + return TURRET_NOT_TARGET + + var/target_suit + var/target_weapon + switch(lasercolor) + if("b") + target_suit = /obj/item/clothing/suit/redtag + target_weapon = /obj/item/weapon/gun/energy/laser/redtag + if("r") + target_suit = /obj/item/clothing/suit/bluetag + target_weapon = /obj/item/weapon/gun/energy/laser/bluetag + + + if(target_suit)//Lasertag turrets target the opposing team, how great is that? -Sieve + if((istype(L.r_hand, target_weapon)) || (istype(L.l_hand, target_weapon))) + return TURRET_PRIORITY_TARGET + + if(istype(L, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = L + if(istype(H.wear_suit, target_suit)) + return TURRET_PRIORITY_TARGET + if(istype(H.belt, target_weapon)) + return TURRET_SECONDARY_TARGET + + return TURRET_NOT_TARGET \ No newline at end of file diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 84d6915556c..e7a064ff077 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -1,636 +1,589 @@ -/* - Portable Turrets: - +/* Portable Turrets: Constructed from metal, a gun of choice, and a prox sensor. - Gun can be a taser or laser or energy gun. - This code is slightly more documented than normal, as requested by XSI on IRC. - */ - /obj/machinery/porta_turret name = "turret" icon = 'icons/obj/turrets.dmi' icon_state = "grey_target_prism" anchored = 1 layer = 3 - invisibility = INVISIBILITY_LEVEL_TWO // the turret is invisible if it's inside its cover + invisibility = INVISIBILITY_LEVEL_TWO //the turret is invisible if it's inside its cover density = 1 - use_power = 1 // this turret uses and requires power - idle_power_usage = 50 // when inactive, this turret takes up constant 50 Equipment power - active_power_usage = 300// when active, this turret takes up constant 300 Equipment power - req_access = list(access_security) - power_channel = EQUIP // drains power from the EQUIPMENT channel + use_power = 1 //this turret uses and requires power + idle_power_usage = 50 //when inactive, this turret takes up constant 50 Equipment power + active_power_usage = 300 //when active, this turret takes up constant 300 Equipment power + req_access = null + req_one_access = list(access_security, access_heads) + power_channel = EQUIP //drains power from the EQUIPMENT channel - var/lasercolor = "" // Something to do with lasertag turrets, blame Sieve for not adding a comment. - var/raised = 0 // if the turret cover is "open" and the turret is raised - var/raising= 0 // if the turret is currently opening or closing its cover - var/health = 80 // the turret's health - var/locked = 1 // if the turret's behaviour control access is locked + var/raised = 0 //if the turret cover is "open" and the turret is raised + var/raising= 0 //if the turret is currently opening or closing its cover + var/health = 80 //the turret's health + var/locked = 1 //if the turret's behaviour control access is locked + var/controllock = 0 //if the turret responds to control panels - var/installation // the type of weapon installed - var/gun_charge = 0 // the charge of the gun inserted + var/installation = /obj/item/weapon/gun/energy/gun/turret //the type of weapon installed + var/gun_charge = 0 //the charge of the gun inserted var/projectile = null //holder for bullettype - var/eprojectile = null//holder for the shot when emagged - var/reqpower = 0 //holder for power needed - var/sound = null//So the taser can have sound - var/iconholder = null//holder for the icon_state - var/egun = null//holder to handle certain guns switching bullettypes + var/eprojectile = null //holder for the shot when emagged + var/reqpower = 500 //holder for power needed + var/iconholder = null //holder for the icon_state. 1 for orange sprite, null for blue. + var/egun = null //holder to handle certain guns switching bullettypes - var/obj/machinery/porta_turret_cover/cover = null // the cover that is covering this turret - var/last_fired = 0 // 1: if the turret is cooling down from a shot, 0: turret is ready to fire - var/shot_delay = 15 // 1.5 seconds between each shot + var/obj/machinery/porta_turret_cover/cover = null //the cover that is covering this turret + var/last_fired = 0 //1: if the turret is cooling down from a shot, 0: turret is ready to fire + var/shot_delay = 15 //1.5 seconds between each shot - var/check_records = 1 // checks if it can use the security records - var/criminals = 1 // checks if it can shoot people on arrest - var/auth_weapons = 0 // checks if it can shoot people that have a weapon they aren't authorized to have - var/stun_all = 0 // if this is active, the turret shoots everything that isn't security or head of staff - var/check_anomalies = 1 // checks if it can shoot at unidentified lifeforms (ie xenos) - var/ai = 0 // if active, will shoot at anything not an AI or cyborg + var/check_arrest = 1 //checks if the perp is set to arrest + var/check_records = 1 //checks if a security record exists at all + var/check_weapons = 0 //checks if it can shoot people that have a weapon they aren't authorized to have + var/check_access = 1 //if this is active, the turret shoots everything that does not meet the access requirements + var/check_anomalies = 1 //checks if it can shoot at unidentified lifeforms (ie xenos) + var/check_synth = 0 //if active, will shoot at anything not an AI or cyborg + var/ailock = 0 // AI cannot use this - var/attacked = 0 // if set to 1, the turret gets pissed off and shoots at people nearby (unless they have sec access!) + var/attacked = 0 //if set to 1, the turret gets pissed off and shoots at people nearby (unless they have sec access!) - //var/emagged = 0 // 1: emagged, 0: not emagged - var/on = 1 // determines if the turret is on + var/enabled = 1 //determines if the turret is on + var/lethal = 0 //whether in lethal or stun mode var/disabled = 0 - var/datum/effect/effect/system/spark_spread/spark_system // the spark system, used for generating... sparks? + var/shot_sound //what sound should play when the turret fires + var/eshot_sound //what sound should play when the emagged turret fires - New() - ..() - icon_state = "[lasercolor]grey_target_prism" - // Sets up a spark system - spark_system = new /datum/effect/effect/system/spark_spread - spark_system.set_up(5, 0, src) - spark_system.attach(src) - sleep(10) - if(!installation)// if for some reason the turret has no gun (ie, admin spawned) it resorts to basic taser shots - projectile = /obj/item/projectile/energy/electrode//holder for the projectile, here it is being set - eprojectile = /obj/item/projectile/beam//holder for the projectile when emagged, if it is different - reqpower = 200 - sound = 1 + var/datum/effect/effect/system/spark_spread/spark_system //the spark system, used for generating... sparks? + + var/wrenching = 0 + var/last_target //last target fired at, prevents turrets from erratically firing at all valid targets in range + +/obj/machinery/porta_turret/stationary + lethal = 1 + installation = /obj/item/weapon/gun/energy/laser + +/obj/machinery/porta_turret/New() + ..() + icon_state = "grey_target_prism" + //Sets up a spark system + spark_system = new /datum/effect/effect/system/spark_spread + spark_system.set_up(5, 0, src) + spark_system.attach(src) + + cover = new /obj/machinery/porta_turret_cover(loc) + cover.Parent_Turret = src + setup() + +/obj/machinery/porta_turret/proc/setup() + var/obj/item/weapon/gun/energy/E = installation //All energy-based weapons are applicable + //var/obj/item/ammo_casing/shottype = E.projectile_type + + projectile = initial(E.projectile_type) + eprojectile = projectile + shot_sound = initial(E.fire_sound) + eshot_sound = shot_sound + + weapon_setup(installation) + +/obj/machinery/porta_turret/proc/weapon_setup(var/guntype) + switch(guntype) + if(/obj/item/weapon/gun/energy/laser/practice) iconholder = 1 - else - var/obj/item/weapon/gun/energy/E=new installation - // All energy-based weapons are applicable - switch(E.type) - if(/obj/item/weapon/gun/energy/laser/bluetag) - projectile = /obj/item/projectile/lasertag/blue - eprojectile = /obj/item/projectile/lasertag/omni//This bolt will stun ERRYONE with a vest - iconholder = null - reqpower = 100 - lasercolor = "b" - req_access = list(access_maint_tunnels) - check_records = 0 - criminals = 0 - auth_weapons = 1 - stun_all = 0 - check_anomalies = 0 - shot_delay = 30 + eprojectile = /obj/item/projectile/beam - if(/obj/item/weapon/gun/energy/laser/redtag) - projectile = /obj/item/projectile/lasertag/red - eprojectile = /obj/item/projectile/lasertag/omni - iconholder = null - reqpower = 100 - lasercolor = "r" - req_access = list(access_maint_tunnels) - check_records = 0 - criminals = 0 - auth_weapons = 1 - stun_all = 0 - check_anomalies = 0 - shot_delay = 30 +// if(/obj/item/weapon/gun/energy/laser/practice/sc_laser) +// iconholder = 1 +// eprojectile = /obj/item/projectile/beam - if(/obj/item/weapon/gun/energy/laser/practice) - projectile = /obj/item/projectile/practice - eprojectile = /obj/item/projectile/beam - iconholder = null - reqpower = 100 + if(/obj/item/weapon/gun/energy/laser/retro) + iconholder = 1 - if(/obj/item/weapon/gun/energy/pulse_rifle) - projectile = /obj/item/projectile/beam/pulse - eprojectile = projectile - iconholder = null - reqpower = 700 +// if(/obj/item/weapon/gun/energy/retro/sc_retro) +// iconholder = 1 - if(/obj/item/weapon/gun/energy/staff) - projectile = /obj/item/projectile/change - eprojectile = projectile - iconholder = 1 - reqpower = 700 + if(/obj/item/weapon/gun/energy/laser/captain) + iconholder = 1 - if(/obj/item/weapon/gun/energy/ionrifle) - projectile = /obj/item/projectile/ion - eprojectile = projectile - iconholder = 1 - reqpower = 700 + if(/obj/item/weapon/gun/energy/lasercannon) + iconholder = 1 - if(/obj/item/weapon/gun/energy/advtaser) - projectile = /obj/item/projectile/energy/electrode - eprojectile = projectile - iconholder = 1 - reqpower = 200 + if(/obj/item/weapon/gun/energy/taser) + eprojectile = /obj/item/projectile/beam + eshot_sound = 'sound/weapons/Laser.ogg' - if(/obj/item/weapon/gun/energy/stunrevolver) - projectile = /obj/item/projectile/energy/electrode - eprojectile = projectile - iconholder = 1 - reqpower = 200 + if(/obj/item/weapon/gun/energy/stunrevolver) + eprojectile = /obj/item/projectile/beam + eshot_sound = 'sound/weapons/Laser.ogg' - if(/obj/item/weapon/gun/energy/lasercannon) - projectile = /obj/item/projectile/beam/heavylaser - eprojectile = projectile - iconholder = null - reqpower = 600 + if(/obj/item/weapon/gun/energy/gun) + eprojectile = /obj/item/projectile/beam //If it has, going to kill mode + eshot_sound = 'sound/weapons/Laser.ogg' + egun = 1 - if(/obj/item/weapon/gun/energy/decloner) - projectile = /obj/item/projectile/energy/declone - eprojectile = projectile - iconholder = null - reqpower = 600 - - if(/obj/item/weapon/gun/energy/kinetic_accelerator/crossbow/large) - projectile = /obj/item/projectile/energy/bolt/large - eprojectile = projectile - iconholder = null - reqpower = 125 - - if(/obj/item/weapon/gun/energy/kinetic_accelerator/crossbow) - projectile = /obj/item/projectile/energy/bolt - eprojectile = projectile - iconholder = null - reqpower = 50 - - if(/obj/item/weapon/gun/energy/laser) - projectile = /obj/item/projectile/beam - eprojectile = projectile - iconholder = null - reqpower = 500 - - else // Energy gun shots - projectile = /obj/item/projectile/energy/electrode// if it hasn't been emagged, it uses normal taser shots - eprojectile = /obj/item/projectile/beam//If it has, going to kill mode - iconholder = 1 - egun = 1 - reqpower = 200 - - Destroy() - // deletes its own cover with it - del(cover) - ..() - - -/obj/machinery/porta_turret/attack_ai(mob/user as mob) - return attack_hand(user) - -/obj/machinery/porta_turret/attack_hand(mob/user as mob) - . = ..() - if (.) - return - var/dat - - // The browse() text, similar to ED-209s and beepskies. - if(!(src.lasercolor))//Lasertag turrets have less options - dat += text({" -Automatic Portable Turret Installation

    -Status: []
    -Behaviour controls are [src.locked ? "locked" : "unlocked"]"}, - -"[src.on ? "On" : "Off"]" ) - - if(!src.locked) - dat += text({"
    -Check for Weapon Authorization: []
    -Check Security Records: []
    -Neutralize Identified Criminals: []
    -Neutralize All Non-Security and Non-Command Personnel: []
    -Neutralize All Unidentified Life Signs: []
    "}, - -"[src.auth_weapons ? "Yes" : "No"]", -"[src.check_records ? "Yes" : "No"]", -"[src.criminals ? "Yes" : "No"]", -"[stun_all ? "Yes" : "No"]", -"[check_anomalies ? "Yes" : "No"]" ) - else - if(istype(user,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - if(((src.lasercolor) == "b") && (istype(H.wear_suit, /obj/item/clothing/suit/redtag))) - return - if(((src.lasercolor) == "r") && (istype(H.wear_suit, /obj/item/clothing/suit/bluetag))) - return - dat += text({" -Automatic Portable Turret Installation

    -Status: []
    "}, - -"[src.on ? "On" : "Off"]" ) - - - user << browse("Automatic Portable Turret Installation[dat]", "window=autosec") - onclose(user, "autosec") - return - -/obj/machinery/porta_turret/Topic(href, href_list) - if (..()) - return - usr.set_machine(src) - src.add_fingerprint(usr) - if ((href_list["power"]) && (src.allowed(usr))) - if(anchored) // you can't turn a turret on/off if it's not anchored/secured - on = !on // toggle on/off - else - usr << "\red It has to be secured first!" - - updateUsrDialog() - return - - switch(href_list["operation"]) - // toggles customizable behavioural protocols - - if ("authweapon") - src.auth_weapons = !src.auth_weapons - if ("checkrecords") - src.check_records = !src.check_records - if ("shootcrooks") - src.criminals = !src.criminals - if("shootall") - stun_all = !stun_all - updateUsrDialog() - - -/obj/machinery/porta_turret/power_change() + if(/obj/item/weapon/gun/energy/gun/nuclear) + eprojectile = /obj/item/projectile/beam //If it has, going to kill mode + eshot_sound = 'sound/weapons/Laser.ogg' + egun = 1 + + if(/obj/item/weapon/gun/energy/gun/turret) + eprojectile = /obj/item/projectile/beam //If it has, going to copypaste mode + eshot_sound = 'sound/weapons/Laser.ogg' + egun = 1 +/obj/machinery/porta_turret/update_icon() if(!anchored) icon_state = "turretCover" return if(stat & BROKEN) - icon_state = "[lasercolor]destroyed_target_prism" + icon_state = "destroyed_target_prism" else - if( powered() ) - if (on) - if (installation == /obj/item/weapon/gun/energy/laser || installation == /obj/item/weapon/gun/energy/pulse_rifle) - // laser guns and pulse rifles have an orange icon - icon_state = "[lasercolor]orange_target_prism" + if(powered()) + if(enabled) + if(iconholder) + //lasers have a orange icon + icon_state = "orange_target_prism" else - // anything else has a blue icon - icon_state = "[lasercolor]target_prism" + //almost everything has a blue icon + icon_state = "target_prism" else - icon_state = "[lasercolor]grey_target_prism" - stat &= ~NOPOWER + icon_state = "grey_target_prism" else - spawn(rand(0, 15)) - src.icon_state = "[lasercolor]grey_target_prism" - stat |= NOPOWER + icon_state = "grey_target_prism" + +/obj/machinery/porta_turret/Destroy() + //deletes its own cover with it + qdel(cover) // qdel + ..() + +/obj/machinery/porta_turret/proc/isLocked(mob/user) + if(ailock && (isrobot(user) || isAI(user))) + user << "There seems to be a firewall preventing you from accessing this device." + return 1 + + if(locked && !(isrobot(user) || isAI(user))) + user << "Access denied." + return 1 + + return 0 + +/obj/machinery/porta_turret/attack_ai(mob/user) + if(isLocked(user)) + return + + ui_interact(user) + +/obj/machinery/porta_turret/attack_hand(mob/user) + if(isLocked(user)) + return + + ui_interact(user) + +/obj/machinery/porta_turret/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] + data["access"] = !isLocked(user) + data["locked"] = locked + data["enabled"] = enabled + data["is_lethal"] = 1 + data["lethal"] = lethal + + if(data["access"]) + var/settings[0] + settings[++settings.len] = list("category" = "Neutralize All Non-Synthetics", "setting" = "check_synth", "value" = check_synth) + settings[++settings.len] = list("category" = "Check Weapon Authorization", "setting" = "check_weapons", "value" = check_weapons) + settings[++settings.len] = list("category" = "Check Security Records", "setting" = "check_records", "value" = check_records) + settings[++settings.len] = list("category" = "Check Arrest Status", "setting" = "check_arrest", "value" = check_arrest) + settings[++settings.len] = list("category" = "Check Access Authorization", "setting" = "check_access", "value" = check_access) + settings[++settings.len] = list("category" = "Check Misc. Lifeforms", "setting" = "check_anomalies", "value" = check_anomalies) + data["settings"] = settings + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "turret_control.tmpl", "Turret Controls", 500, 300) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + +/obj/machinery/porta_turret/proc/HasController() + var/area/A = get_area(src) + return A && A.turret_controls.len > 0 + +/obj/machinery/porta_turret/CanUseTopic(var/mob/user) + if(HasController()) + user << "Turrets can only be controlled using the assigned turret controller." + return STATUS_CLOSE + + if(isLocked(user)) + return STATUS_CLOSE + + if(!anchored) + usr << "\The [src] has to be secured first!" + return STATUS_CLOSE + + return STATUS_INTERACTIVE + +/obj/machinery/porta_turret/Topic(href, href_list, var/nowindow = 0) + if(..()) + return 1 + + if(href_list["command"] && href_list["value"]) + var/value = text2num(href_list["value"]) + if(href_list["command"] == "enable") + enabled = value + else if(href_list["command"] == "lethal") + lethal = value + else if(href_list["command"] == "check_synth") + check_synth = value + else if(href_list["command"] == "check_weapons") + check_weapons = value + else if(href_list["command"] == "check_records") + check_records = value + else if(href_list["command"] == "check_arrest") + check_arrest = value + else if(href_list["command"] == "check_access") + check_access = value + else if(href_list["command"] == "check_anomalies") + check_anomalies = value + + return 1 + +/obj/machinery/porta_turret/power_change() + if(powered()) + stat &= ~NOPOWER + update_icon() + else + spawn(rand(0, 15)) + stat |= NOPOWER + update_icon() - -/obj/machinery/porta_turret/attackby(obj/item/W as obj, mob/user as mob) +/obj/machinery/porta_turret/attackby(obj/item/I, mob/user) if(stat & BROKEN) - if(istype(W, /obj/item/weapon/crowbar)) + if(istype(I, /obj/item/weapon/crowbar)) + //If the turret is destroyed, you can remove it with a crowbar to + //try and salvage its components + user << "You begin prying the metal coverings off." + if(do_after(user, 20)) + if(prob(70)) + user << "You remove the turret and salvage some components." + if(installation) + var/obj/item/weapon/gun/energy/Gun = new installation(loc) + Gun.power_supply.charge = gun_charge + Gun.update_icon() + if(prob(50)) + new /obj/item/stack/sheet/metal(loc, rand(1,4)) + if(prob(50)) + new /obj/item/device/assembly/prox_sensor(loc) + else + user << "You remove the turret but did not manage to salvage anything." + qdel(src) // qdel - // If the turret is destroyed, you can remove it with a crowbar to - // try and salvage its components - user << "You begin prying the metal coverings off." - sleep(20) - if(prob(70)) - user << "You remove the turret and salvage some components." - if(installation) - var/obj/item/weapon/gun/energy/Gun = new installation(src.loc) - Gun.power_supply.charge=gun_charge - Gun.update_icon() - lasercolor = null - if(prob(50)) new /obj/item/stack/sheet/metal( loc, rand(1,4)) - if(prob(50)) new /obj/item/device/assembly/prox_sensor(locate(x,y,z)) - else - user << "You remove the turret but did not manage to salvage anything." - del(src) + else if((istype(I, /obj/item/weapon/wrench))) + if(enabled || raised) + user << "You cannot unsecure an active turret!" + return + if(wrenching) + user << "Someone is already [anchored ? "un" : ""]securing the turret!" + return + if(!anchored && isinspace()) + user << "Cannot secure turrets in space!" + return + user.visible_message( \ + "[user] begins [anchored ? "un" : ""]securing the turret.", \ + "You begin [anchored ? "un" : ""]securing the turret." \ + ) - if ((istype(W, /obj/item/weapon/card/emag)) && (!src.emagged)) - // Emagging the turret makes it go bonkers and stun everyone. It also makes - // the turret shoot much, much faster. + wrenching = 1 + if(do_after(user, 50)) + //This code handles moving the turret around. After all, it's a portable turret! + if(!anchored) + playsound(loc, 'sound/items/Ratchet.ogg', 100, 1) + anchored = 1 + invisibility = INVISIBILITY_LEVEL_TWO + update_icon() + user << "You secure the exterior bolts on the turret." + create_cover() + else if(anchored) + playsound(loc, 'sound/items/Ratchet.ogg', 100, 1) + anchored = 0 + user << "You unsecure the exterior bolts on the turret." + invisibility = 0 + update_icon() + qdel(cover) //deletes the cover, and the turret instance itself becomes its own cover. - qdel + wrenching = 0 - user << "\red You short out [src]'s threat assessment circuits." - spawn(0) - for(var/mob/O in hearers(src, null)) - O.show_message("\red [src] hums oddly...", 1) - emagged = 1 - src.on = 0 // turns off the turret temporarily - sleep(60) // 6 seconds for the traitor to gtfo of the area before the turret decides to ruin his shit - on = 1 // turns it back on. The cover popUp() popDown() are automatically called in process(), no need to define it here - - else if((istype(W, /obj/item/weapon/wrench)) && (!on)) - if(raised) return - // This code handles moving the turret around. After all, it's a portable turret! - - if(!anchored) - anchored = 1 - invisibility = INVISIBILITY_LEVEL_TWO - icon_state = "[lasercolor]grey_target_prism" - user << "You secure the exterior bolts on the turret." - cover=new/obj/machinery/porta_turret_cover(src.loc) // create a new turret. While this is handled in process(), this is to workaround a bug where the turret becomes invisible for a split second - cover.Parent_Turret = src // make the cover's parent src + else if(istype(I, /obj/item/weapon/card/id)||istype(I, /obj/item/device/pda)) + //Behavior lock/unlock mangement + if(allowed(user)) + locked = !locked + user << "Controls are now [locked ? "locked" : "unlocked"]." + updateUsrDialog() else - anchored = 0 - user << "You unsecure the exterior bolts on the turret." - icon_state = "turretCover" - invisibility = 0 - del(cover) // deletes the cover, and the turret instance itself becomes its own cover. - - else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) - // Behavior lock/unlock mangement - if (allowed(user)) - locked = !src.locked - user << "Controls are now [locked ? "locked." : "unlocked."]" - else - user << "\red Access denied." + user << "Access denied." else - // if the turret was attacked with the intention of harming it: - src.health -= W.force * 0.5 - if (src.health <= 0) - src.die() - if ((W.force * 0.5) > 1) // if the force of impact dealt at least 1 damage, the turret gets pissed off + //if the turret was attacked with the intention of harming it: + user.changeNext_move(CLICK_CD_MELEE) + take_damage(I.force * 0.5) + playsound(src.loc, 'sound/weapons/smash.ogg', 60, 1) + if(I.force * 0.5 > 1) //if the force of impact dealt at least 1 damage, the turret gets pissed off if(!attacked && !emagged) attacked = 1 spawn() sleep(60) attacked = 0 + ..() + +/obj/machinery/porta_turret/emag_act(user as mob) + if(!emagged) + //Emagging the turret makes it go bonkers and stun everyone. It also makes + //the turret shoot much, much faster. + user << "You short out [src]'s threat assessment circuits." + visible_message("[src] hums oddly...") + emagged = 1 + iconholder = 1 + controllock = 1 + enabled = 0 //turns off the turret temporarily + sleep(60) //6 seconds for the traitor to gtfo of the area before the turret decides to ruin his shit + enabled = 1 //turns it back on. The cover popUp() popDown() are automatically called in process(), no need to define it here +/obj/machinery/porta_turret/proc/take_damage(var/force) + health -= force + if (force > 5 && prob(45)) + spark_system.start() + if(health <= 0) + die() //the death process :( +/obj/machinery/porta_turret/bullet_act(obj/item/projectile/Proj) -/obj/machinery/porta_turret/bullet_act(var/obj/item/projectile/Proj) - if(on) + if(Proj.damage_type == HALLOSS || Proj.damage_type == STAMINA) + return + + if(enabled) if(!attacked && !emagged) attacked = 1 spawn() sleep(60) attacked = 0 - if((Proj.damage_type == BRUTE || Proj.damage_type == BURN)) - health -= Proj.damage - ..() - if(prob(45) && Proj.damage > 0) src.spark_system.start() - if (src.health <= 0) - src.die() // the death process :( - if((src.lasercolor == "b") && (src.disabled == 0)) - if(istype(Proj, /obj/item/projectile/lasertag/red)) - src.disabled = 1 - del (Proj) - sleep(100) - src.disabled = 0 - if((src.lasercolor == "r") && (src.disabled == 0)) - if(istype(Proj, /obj/item/projectile/lasertag/blue)) - src.disabled = 1 - del (Proj) - sleep(100) - src.disabled = 0 - return + if((Proj.damage_type == BRUTE || Proj.damage_type == BURN)) + take_damage(Proj.damage) /obj/machinery/porta_turret/emp_act(severity) - if(on) - // if the turret is on, the EMP no matter how severe disables the turret for a while - // and scrambles its settings, with a slight chance of having an emag effect - check_records=pick(0,1) - criminals=pick(0,1) - auth_weapons=pick(0,1) - stun_all=pick(0,0,0,0,1) // stun_all is a pretty big deal, so it's least likely to get turned on - if(prob(5)) emagged=1 - on=0 + if(enabled) + //if the turret is on, the EMP no matter how severe disables the turret for a while + //and scrambles its settings, with a slight chance of having an emag effect + check_arrest = prob(50) + check_records = prob(50) + check_weapons = prob(50) + check_access = prob(20) // check_access is a pretty big deal, so it's least likely to get turned on + check_anomalies = prob(50) + if(prob(5)) + emagged = 1 + + enabled=0 sleep(rand(60,600)) - if(!on) - on=1 + if(!enabled) + enabled=1 ..() /obj/machinery/porta_turret/ex_act(severity) - if(severity >= 3) // turret dies if an explosion touches it! - qdel(src) - else - src.die() - -/obj/machinery/porta_turret/proc/die() // called when the turret dies, ie, health <= 0 - src.health = 0 - src.density = 0 - src.stat |= BROKEN // enables the BROKEN bit - src.icon_state = "[lasercolor]destroyed_target_prism" - invisibility=0 - src.spark_system.start() // creates some sparks because they look cool - src.density=1 - qdel(cover) // deletes the cover - no need on keeping it there! + switch (severity) + if (1) + qdel(src) + if (2) + if (prob(25)) + qdel(src) + else + take_damage(150) //should instakill most turrets + if (3) + take_damage(50) +/obj/machinery/porta_turret/proc/die() //called when the turret dies, ie, health <= 0 + health = 0 + density = 0 + stat |= BROKEN //enables the BROKEN bit + invisibility = 0 + spark_system.start() //creates some sparks because they look cool + density = 1 + update_icon() + del(cover) //deletes the cover - no need on keeping it there! - del +/obj/machinery/porta_turret/proc/create_cover() + if(cover == null && anchored) + cover = new /obj/machinery/porta_turret_cover(loc) //if the turret has no cover and is anchored, give it a cover + cover.Parent_Turret = src //assign the cover its Parent_Turret, which would be this (src) /obj/machinery/porta_turret/process() - // the main machinery process + //the main machinery process - //set background = 1 + set background = BACKGROUND_ENABLED - if(src.cover==null && anchored) // if it has no cover and is anchored - if (stat & BROKEN) // if the turret is borked - del(cover) // delete its cover, assuming it has one. Workaround for a pesky little bug + if(cover == null && anchored) //if it has no cover and is anchored + if(stat & BROKEN) //if the turret is borked + qdel(cover) //delete its cover, assuming it has one. Workaround for a pesky little bug - qdel else - - src.cover = new /obj/machinery/porta_turret_cover(src.loc) // if the turret has no cover and is anchored, give it a cover - src.cover.Parent_Turret = src // assign the cover its Parent_Turret, which would be this (src) + create_cover() if(stat & (NOPOWER|BROKEN)) - // if the turret has no power or is broken, make the turret pop down if it hasn't already + //if the turret has no power or is broken, make the turret pop down if it hasn't already popDown() return - if(!on) - // if the turret is off, make it pop down + if(!enabled) + //if the turret is off, make it pop down popDown() return - var/list/targets = list() // list of primary targets - var/list/secondarytargets = list() // targets that are least important + var/list/targets = list() //list of primary targets + var/list/secondarytargets = list() //targets that are least important - if(src.check_anomalies) // if its set to check for xenos/carps, check for non-mob "crittersssss"(And simple_animals) - for(var/mob/living/simple_animal/C in view(7,src)) - if(C.stat) - continue - // Ignore lazarus-injected mobs. - if(C.faction == "lazarus") - continue - targets += C + for(var/obj/mecha/ME in view(7,src)) + assess_and_assign(ME.occupant, targets, secondarytargets) - for (var/mob/living/carbon/C in view(7,src)) // loops through all living carbon-based lifeforms in view(12) - if(istype(C, /mob/living/carbon/alien) && src.check_anomalies) // git those fukken xenos - if(!C.stat) // if it's dead/dying, there's no need to keep shooting at it. - targets += C + for(var/obj/spacepod/SP in view(7,src)) + assess_and_assign(SP.occupant, targets, secondarytargets) + + for(var/obj/vehicle/train/T in view(7,src)) + assess_and_assign(T.load, targets, secondarytargets) - else - if(emagged) // if emagged, HOLY SHIT EVERYONE IS DANGEROUS beep boop beep - targets += C - else - if (C.stat || C.handcuffed) // if the perp is handcuffed or dead/dying, no need to bother really - continue // move onto next potential victim! + for(var/mob/living/C in view(7,src)) //loops through all living lifeforms in view + assess_and_assign(C, targets, secondarytargets) - var/dst = get_dist(src, C) // if it's too far away, why bother? - if (dst > 7) - continue + if(!tryToShootAt(targets)) + if(!tryToShootAt(secondarytargets)) // if no valid targets, go for secondary targets + spawn() + popDown() // no valid targets, close the cover - if(ai) // If it's set to attack all nonsilicons, target them! - if(C.lying) - if(lasercolor) - continue - else - secondarytargets += C - continue - else - targets += C - continue +/obj/machinery/porta_turret/proc/assess_and_assign(var/mob/living/L, var/list/targets, var/list/secondarytargets) + switch(assess_living(L)) + if(TURRET_PRIORITY_TARGET) + targets += L + if(TURRET_SECONDARY_TARGET) + secondarytargets += L - if (istype(C, /mob/living/carbon/human)) // if the target is a human, analyze threat level - if(src.assess_perp(C)<4) - continue // if threat level < 4, keep going +/obj/machinery/porta_turret/proc/assess_living(var/mob/living/L) + if(!istype(L)) + return TURRET_NOT_TARGET - else if (istype(C, /mob/living/carbon/monkey)) - continue // Don't target monkeys or borgs/AIs you dumb shit + if(L.invisibility >= INVISIBILITY_LEVEL_ONE) // Cannot see him. see_invisible is a mob-var + return TURRET_NOT_TARGET - if (C.lying) // if the perp is lying down, it's still a target but a less-important target - secondarytargets += C - continue + if(!L) + return TURRET_NOT_TARGET - targets += C // if the perp has passed all previous tests, congrats, it is now a "shoot-me!" nominee + // If emagged not even the dead get a rest + if(emagged) + return L.stat ? TURRET_SECONDARY_TARGET : TURRET_PRIORITY_TARGET - if (targets.len>0) // if there are targets to shoot + if(issilicon(L)) // Don't target silica + return TURRET_NOT_TARGET - var/atom/t = pick(targets) // pick a perp from the list of targets. Targets go first because they are the most important + if(L.stat) //if the perp is dead/dying, no need to bother really + return TURRET_NOT_TARGET //move onto next potential victim! - if (istype(t, /mob/living)) // if a mob - var/mob/living/M = t // simple typecasting - if (M.stat!=2) // if the target is not dead - spawn() popUp() // pop the turret up if it's not already up. - dir=get_dir(src,M) // even if you can't shoot, follow the target - spawn() shootAt(M) // shoot the target, finally + var/dst = get_dist(src, L) //if it's too far away, why bother? + if(dst > 7) + return 0 - else - if(secondarytargets.len>0) // if there are no primary targets, go for secondary targets - var/mob/t = pick(secondarytargets) - if (istype(t, /mob/living)) - if (t.stat!=2) - spawn() popUp() - dir=get_dir(src,t) - shootAt(t) - else - spawn() popDown() + if(check_synth) //If it's set to attack all non-silicons, target them! + if(L.lying) + return lethal ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET + return TURRET_PRIORITY_TARGET -/obj/machinery/porta_turret/proc - popUp() // pops the turret up - if(disabled) - return - if(raising || raised) return - if(stat & BROKEN) return - invisibility=0 - raising=1 - flick("popup",cover) - sleep(5) - sleep(5) - raising=0 - cover.icon_state="openTurretCover" - raised=1 - layer=4 + if(iscuffed(L)) // If the target is handcuffed, leave it alone + return TURRET_NOT_TARGET - popDown() // pops the turret down - if(disabled) - return - if(raising || !raised) return - if(stat & BROKEN) return - layer=3 - raising=1 - flick("popdown",cover) - sleep(10) - raising=0 - cover.icon_state="turretCover" - raised=0 - invisibility=2 - icon_state="[lasercolor]grey_target_prism" + if(isanimal(L) || ismonkey(L)) // Animals are not so dangerous + return check_anomalies ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET + if(isalien(L)) // Xenos are dangerous + return check_anomalies ? TURRET_PRIORITY_TARGET : TURRET_NOT_TARGET + if(ishuman(L)) //if the target is a human, analyze threat level + if(assess_perp(L, check_weapons, check_records, check_arrest) < 4) + return TURRET_NOT_TARGET //if threat level < 4, keep going -/obj/machinery/porta_turret/proc/assess_perp(mob/living/carbon/human/perp as mob) - var/threatcount = 0 // the integer returned + if(L.lying) //if the perp is lying down, it's still a target but a less-important target + return lethal ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET - if(src.emagged) return 10 // if emagged, always return 10. + return TURRET_PRIORITY_TARGET //if the perp has passed all previous tests, congrats, it is now a "shoot-me!" nominee - if((stun_all && !src.allowed(perp)) || attacked && !src.allowed(perp)) - // if the turret has been attacked or is angry, target all non-sec people - if(!src.allowed(perp)) - return 10 +/obj/machinery/porta_turret/proc/tryToShootAt(var/list/mob/living/targets) + if(targets.len && last_target && (last_target in targets) && target(last_target)) + return 1 - if(auth_weapons) // check for weapon authorization - if((isnull(perp.wear_id)) || (istype(perp.wear_id.GetID(), /obj/item/weapon/card/id/syndicate))) - - if((src.allowed(perp)) && !(src.lasercolor)) // if the perp has security access, return 0 - return 0 - - if((istype(perp.l_hand, /obj/item/weapon/gun) && !istype(perp.l_hand, /obj/item/weapon/gun/projectile/shotgun)) || istype(perp.l_hand, /obj/item/weapon/melee/baton)) - threatcount += 4 - - if((istype(perp.r_hand, /obj/item/weapon/gun) && !istype(perp.r_hand, /obj/item/weapon/gun/projectile/shotgun)) || istype(perp.r_hand, /obj/item/weapon/melee/baton)) - threatcount += 4 - - if(istype(perp.belt, /obj/item/weapon/gun) || istype(perp.belt, /obj/item/weapon/melee/baton)) - threatcount += 2 - - if((src.lasercolor) == "b")//Lasertag turrets target the opposing team, how great is that? -Sieve - threatcount = 0//But does not target anyone else - if(istype(perp.wear_suit, /obj/item/clothing/suit/redtag)) - threatcount += 4 - if((istype(perp.r_hand,/obj/item/weapon/gun/energy/laser/redtag)) || (istype(perp.l_hand,/obj/item/weapon/gun/energy/laser/redtag))) - threatcount += 4 - if(istype(perp.belt, /obj/item/weapon/gun/energy/laser/redtag)) - threatcount += 2 - - if((src.lasercolor) == "r") - threatcount = 0 - if(istype(perp.wear_suit, /obj/item/clothing/suit/bluetag)) - threatcount += 4 - if((istype(perp.r_hand,/obj/item/weapon/gun/energy/laser/bluetag)) || (istype(perp.l_hand,/obj/item/weapon/gun/energy/laser/bluetag))) - threatcount += 4 - if(istype(perp.belt, /obj/item/weapon/gun/energy/laser/bluetag)) - threatcount += 2 - - if (src.check_records) // if the turret can check the records, check if they are set to *Arrest* on records - for (var/datum/data/record/E in data_core.general) - - var/perpname = perp.name - if (perp.wear_id) - var/obj/item/weapon/card/id/id = perp.wear_id.GetID() - if (id) - perpname = id.registered_name - - if (E.fields["name"] == perpname) - for (var/datum/data/record/R in data_core.security) - if ((R.fields["id"] == E.fields["id"]) && (R.fields["criminal"] == "*Arrest*")) - threatcount = 4 - break - - - - return threatcount - - - - - -/obj/machinery/porta_turret/proc/shootAt(var/atom/movable/target) // shoots at a target + while(targets.len > 0) + var/mob/living/M = pick(targets) + targets -= M + if(target(M)) + return 1 + +/obj/machinery/porta_turret/proc/popUp() //pops the turret up if(disabled) return + if(raising || raised) + return + if(stat & BROKEN) + return + playsound(get_turf(src), 'sound/effects/turret/open.wav', 60, 1) + invisibility = 0 + raising = 1 + flick("popup", cover) + sleep(10) + raising = 0 + cover.icon_state = "openTurretCover" + raised = 1 + layer = 4 + update_icon() - if(lasercolor && (istype(target,/mob/living/carbon/human))) - var/mob/living/carbon/human/H = target - if(H.lying) +/obj/machinery/porta_turret/proc/popDown() //pops the turret down + last_target = null + if(disabled) + return + if(raising || !raised) + return + if(stat & BROKEN) + return + playsound(get_turf(src), 'sound/effects/turret/open.wav', 60, 1) + layer = 3 + raising = 1 + flick("popdown", cover) + sleep(10) + raising = 0 + cover.icon_state = "turretCover" + raised = 0 + invisibility = INVISIBILITY_LEVEL_TWO + update_icon() + +/obj/machinery/porta_turret/on_assess_perp(mob/living/carbon/human/perp) + if((check_access || attacked) && !allowed(perp)) + //if the turret has been attacked or is angry, target all non-authorized personnel, see req_access + return 10 + + return ..() + +/obj/machinery/porta_turret/proc/target(var/mob/living/target) + if(disabled) + return + if(target) + last_target = target + spawn() + popUp() //pop the turret up if it's not already up. + dir = get_dir(src, target) //even if you can't shoot, follow the target + spawn() + shootAt(target) + return 1 + return + +/obj/machinery/porta_turret/proc/shootAt(var/mob/living/target) + //any emagged turrets will shoot extremely fast! This not only is deadly, but drains a lot power! + if(!emagged) //if it hasn't been emagged, it has to obey a cooldown rate + if(last_fired || !raised) //prevents rapid-fire shooting, unless it's been emagged return - - if(!emagged) // if it hasn't been emagged, it has to obey a cooldown rate - if(last_fired || !raised) return // prevents rapid-fire shooting, unless it's been emagged last_fired = 1 spawn() sleep(shot_delay) @@ -638,47 +591,65 @@ Status: []
    "}, var/turf/T = get_turf(src) var/turf/U = get_turf(target) - if (!istype(T) || !istype(U)) + if(!istype(T) || !istype(U)) return - if (!raised) // the turret has to be raised in order to fire - makes sense, right? + if(!raised) //the turret has to be raised in order to fire - makes sense, right? return - // any emagged turrets will shoot extremely fast! This not only is deadly, but drains a lot power! - - if(iconholder) - icon_state = "[lasercolor]target_prism" - else - icon_state = "[lasercolor]orange_target_prism" - if(sound) - playsound(src.loc, 'sound/weapons/Taser.ogg', 75, 1) + update_icon() var/obj/item/projectile/A - if(emagged) - A = new eprojectile( loc ) + if(emagged || lethal) + A = new eprojectile(loc) + playsound(loc, eshot_sound, 75, 1) else - A = new projectile( loc ) - A.original = target.loc - if(!emagged) - use_power(reqpower) - else - use_power((reqpower*2)) - // Shooting Code: + A = new projectile(loc) + playsound(loc, shot_sound, 75, 1) + A.original = target + + // Lethal/emagged turrets use twice the power due to higher energy beams + // Emagged turrets again use twice as much power due to higher firing rates + use_power(reqpower * (2 * (emagged || lethal)) * (2 * emagged)) + + //Shooting Code: A.current = T A.yo = U.y - T.y A.xo = U.x - T.x - spawn( 1 ) + spawn(1) A.process() - return +/datum/turret_checks + var/enabled + var/lethal + var/check_synth + var/check_access + var/check_records + var/check_arrest + var/check_weapons + var/check_anomalies + var/ailock +/obj/machinery/porta_turret/proc/setState(var/datum/turret_checks/TC) + if(controllock) + return + src.enabled = TC.enabled + src.lethal = TC.lethal + src.iconholder = TC.lethal + + check_synth = TC.check_synth + check_access = TC.check_access + check_records = TC.check_records + check_arrest = TC.check_arrest + check_weapons = TC.check_weapons + check_anomalies = TC.check_anomalies + ailock = TC.ailock + + src.power_change() /* - Portable turret constructions - Known as "turret frame"s - */ /obj/machinery/porta_turret_construct @@ -686,66 +657,66 @@ Status: []
    "}, icon = 'icons/obj/turrets.dmi' icon_state = "turret_frame" density=1 - var/build_step = 0 // the current step in the building process - var/finish_name="turret" // the name applied to the product turret - var/installation = null // the gun type installed - var/gun_charge = 0 // the gun charge of the gun type installed + var/target_type = /obj/machinery/porta_turret // The type we intend to build + var/build_step = 0 //the current step in the building process + var/finish_name="turret" //the name applied to the product turret + var/installation = null //the gun type installed + var/gun_charge = 0 //the gun charge of the gun type installed - -/obj/machinery/porta_turret_construct/attackby(obj/item/W as obj, mob/user as mob) - - // this is a bit unweildy but self-explanitory +/obj/machinery/porta_turret_construct/attackby(obj/item/I, mob/user) + //this is a bit unwieldy but self-explanatory switch(build_step) - if(0) // first step - if(istype(W, /obj/item/weapon/wrench) && !anchored) - playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1) - user << "\blue You secure the external bolts." + if(0) //first step + if(istype(I, /obj/item/weapon/wrench) && !anchored) + playsound(loc, 'sound/items/Ratchet.ogg', 100, 1) + user << "You secure the external bolts." anchored = 1 build_step = 1 return - else if(istype(W, /obj/item/weapon/crowbar) && !anchored) - playsound(src.loc, 'sound/items/Crowbar.ogg', 75, 1) - user << "You dismantle the turret construction." + else if(istype(I, /obj/item/weapon/crowbar) && !anchored) + playsound(loc, 'sound/items/Crowbar.ogg', 75, 1) + user << "You dismantle the turret construction." new /obj/item/stack/sheet/metal( loc, 5) - del(src) + qdel(src) // qdel return if(1) - if(istype(W, /obj/item/stack/sheet/metal)) - if(W:amount>=2) // requires 2 metal sheets - user << "\blue You add some metal armor to the interior frame." + if(istype(I, /obj/item/stack/sheet/metal)) + var/obj/item/stack/sheet/metal/M = I + if(M.use(2)) + user << "You add some metal armor to the interior frame." build_step = 2 - W:amount -= 2 icon_state = "turret_frame2" - if(W:amount <= 0) - del(W) - return + else + user << "You need two sheets of metal to continue construction." + return - else if(istype(W, /obj/item/weapon/wrench)) - playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) - user << "You unfasten the external bolts." + else if(istype(I, /obj/item/weapon/wrench)) + playsound(loc, 'sound/items/Ratchet.ogg', 75, 1) + user << "You unfasten the external bolts." anchored = 0 build_step = 0 return if(2) - if(istype(W, /obj/item/weapon/wrench)) - playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1) - user << "\blue You bolt the metal armor into place." + if(istype(I, /obj/item/weapon/wrench)) + playsound(loc, 'sound/items/Ratchet.ogg', 100, 1) + user << "You bolt the metal armor into place." build_step = 3 return - else if(istype(W, /obj/item/weapon/weldingtool)) - var/obj/item/weapon/weldingtool/WT = W - if(!WT.isOn()) return - if (WT.get_fuel() < 5) // uses up 5 fuel. - user << "\red You need more fuel to complete this task." + else if(istype(I, /obj/item/weapon/weldingtool)) + var/obj/item/weapon/weldingtool/WT = I + if(!WT.isOn()) + return + if(WT.get_fuel() < 5) //uses up 5 fuel. + user << "You need more fuel to complete this task." return - playsound(src.loc, pick('sound/items/Welder.ogg', 'sound/items/Welder2.ogg'), 50, 1) + playsound(loc, pick('sound/items/Welder.ogg', 'sound/items/Welder2.ogg'), 50, 1) if(do_after(user, 20)) if(!src || !WT.remove_fuel(5, user)) return build_step = 1 @@ -755,130 +726,143 @@ Status: []
    "}, if(3) - if(istype(W, /obj/item/weapon/gun/energy)) // the gun installation part + if(istype(I, /obj/item/weapon/gun/energy)) //the gun installation part + + if(isrobot(user)) + return + var/obj/item/weapon/gun/energy/E = I //typecasts the item to an energy gun + if(!user.unEquip(I)) + user << "\the [I] is stuck to your hand, you cannot put it in \the [src]" + return + installation = I.type //installation becomes I.type + gun_charge = E.power_supply.charge //the gun's charge is stored in gun_charge + user << "You add [I] to the turret." + + if(istype(installation, /obj/item/weapon/gun/energy/laser/bluetag) || istype(installation, /obj/item/weapon/gun/energy/laser/redtag)) + target_type = /obj/machinery/porta_turret/tag + else + target_type = /obj/machinery/porta_turret - var/obj/item/weapon/gun/energy/E = W // typecasts the item to an energy gun - installation = W.type // installation becomes W.type - gun_charge = E.power_supply.charge // the gun's charge is stored in src.gun_charge - user << "\blue You add \the [W] to the turret." build_step = 4 - del(W) // delete the gun :( + qdel(I) //delete the gun :( qdel return - else if(istype(W, /obj/item/weapon/wrench)) - playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1) - user << "You remove the turret's metal armor bolts." + else if(istype(I, /obj/item/weapon/wrench)) + playsound(loc, 'sound/items/Ratchet.ogg', 100, 1) + user << "You remove the turret's metal armor bolts." build_step = 2 return if(4) - if(isprox(W)) + if(isprox(I)) + if(!user.unEquip(I)) + user << "\the [I] is stuck to your hand, you cannot put it in \the [src]" + return build_step = 5 - user << "\blue You add the prox sensor to the turret." - del(W) + qdel(I) // qdel + user << "You add the prox sensor to the turret." return - // attack_hand() removes the gun + //attack_hand() removes the gun if(5) - if(istype(W, /obj/item/weapon/screwdriver)) - playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1) + if(istype(I, /obj/item/weapon/screwdriver)) + playsound(loc, 'sound/items/Screwdriver.ogg', 100, 1) build_step = 6 - user << "\blue You close the internal access hatch." + user << "You close the internal access hatch." return - // attack_hand() removes the prox sensor + //attack_hand() removes the prox sensor if(6) - if(istype(W, /obj/item/stack/sheet/metal)) - if(W:amount>=2) - user << "\blue You add some metal armor to the exterior frame." + if(istype(I, /obj/item/stack/sheet/metal)) + var/obj/item/stack/sheet/metal/M = I + if(M.use(2)) + user << "You add some metal armor to the exterior frame." build_step = 7 - W:amount -= 2 - if(W:amount <= 0) - del(W) - return + else + user << "You need two sheets of metal to continue construction." + return - else if(istype(W, /obj/item/weapon/screwdriver)) - playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1) + else if(istype(I, /obj/item/weapon/screwdriver)) + playsound(loc, 'sound/items/Screwdriver.ogg', 100, 1) build_step = 5 - user << "You open the internal access hatch." + user << "You open the internal access hatch." return if(7) - if(istype(W, /obj/item/weapon/weldingtool)) - var/obj/item/weapon/weldingtool/WT = W + if(istype(I, /obj/item/weapon/weldingtool)) + var/obj/item/weapon/weldingtool/WT = I if(!WT.isOn()) return - if (WT.get_fuel() < 5) - user << "\red You need more fuel to complete this task." + if(WT.get_fuel() < 5) + user << "You need more fuel to complete this task." - playsound(src.loc, pick('sound/items/Welder.ogg', 'sound/items/Welder2.ogg'), 50, 1) + playsound(loc, pick('sound/items/Welder.ogg', 'sound/items/Welder2.ogg'), 50, 1) if(do_after(user, 30)) - if(!src || !WT.remove_fuel(5, user)) return + if(!src || !WT.remove_fuel(5, user)) + return build_step = 8 - user << "\blue You weld the turret's armor down." + user << "You weld the turret's armor down." - // The final step: create a full turret - var/obj/machinery/porta_turret/Turret = new/obj/machinery/porta_turret(locate(x,y,z)) + //The final step: create a full turret + var/obj/machinery/porta_turret/Turret = new target_type(loc) Turret.name = finish_name - Turret.installation = src.installation - Turret.gun_charge = src.gun_charge + Turret.installation = installation + Turret.gun_charge = gun_charge + Turret.enabled = 0 + Turret.setup() -// Turret.cover=new/obj/machinery/porta_turret_cover(src.loc) +// Turret.cover=new/obj/machinery/porta_turret_cover(loc) // Turret.cover.Parent_Turret=Turret // Turret.cover.name = finish_name - Turret.New() - del(src) + qdel(src) // qdel - else if(istype(W, /obj/item/weapon/crowbar)) - playsound(src.loc, 'sound/items/Crowbar.ogg', 75, 1) - user << "You pry off the turret's exterior armor." - new /obj/item/stack/sheet/metal( loc, 2) + else if(istype(I, /obj/item/weapon/crowbar)) + playsound(loc, 'sound/items/Crowbar.ogg', 75, 1) + user << "You pry off the turret's exterior armor." + new /obj/item/stack/sheet/metal(loc, 2) build_step = 6 return - if (istype(W, /obj/item/weapon/pen)) // you can rename turrets like bots! - var/t = input(user, "Enter new turret name", src.name, src.finish_name) as text - t = copytext(sanitize(t), 1, MAX_MESSAGE_LEN) - if (!t) + if(istype(I, /obj/item/weapon/pen)) //you can rename turrets like bots! + var/t = input(user, "Enter new turret name", name, finish_name) as text + t = sanitize(copytext(t, 1, MAX_MESSAGE_LEN)) + if(!t) return - if (!in_range(src, usr) && src.loc != usr) + if(!in_range(src, usr) && loc != usr) return - src.finish_name = t + finish_name = t return ..() - -/obj/machinery/porta_turret_construct/attack_hand(mob/user as mob) +/obj/machinery/porta_turret_construct/attack_hand(mob/user) switch(build_step) if(4) - if(!installation) return + if(!installation) + return build_step = 3 - var/obj/item/weapon/gun/energy/Gun = new installation(src.loc) - Gun.power_supply.charge=gun_charge + var/obj/item/weapon/gun/energy/Gun = new installation(loc) + Gun.power_supply.charge = gun_charge Gun.update_icon() installation = null gun_charge = 0 - user << "You remove \the [Gun] from the turret frame." + user << "You remove [Gun] from the turret frame." if(5) - user << "You remove the prox sensor from the turret frame." - new/obj/item/device/assembly/prox_sensor(locate(x,y,z)) + user << "You remove the prox sensor from the turret frame." + new /obj/item/device/assembly/prox_sensor(loc) build_step = 4 +/obj/machinery/porta_turret_construct/attack_ai() + return - - - - - - - - +/************************ +* PORTABLE TURRET COVER * +************************/ /obj/machinery/porta_turret_cover name = "turret" @@ -889,179 +873,14 @@ Status: []
    "}, density = 0 var/obj/machinery/porta_turret/Parent_Turret = null +/obj/machinery/porta_turret_cover/attack_ai(mob/user) + return attack_hand(user) - -// The below code is pretty much just recoded from the initial turret object. It's necessary but uncommented because it's exactly the same! - -/obj/machinery/porta_turret_cover/attack_ai(mob/user as mob) - . = ..() - if (.) - return - var/dat - if(!(Parent_Turret.lasercolor)) - dat += text({" -Automatic Portable Turret Installation

    -Status: []
    -Behaviour controls are [Parent_Turret.locked ? "locked" : "unlocked"]"}, - -"[Parent_Turret.on ? "On" : "Off"]" ) - - - dat += text({"
    -Check for Weapon Authorization: []
    -Check Security Records: []
    -Neutralize Identified Criminals: []
    -Neutralize All Non-Security and Non-Command Personnel: []
    -Neutralize All Unidentified Life Signs: []
    "}, - -"[Parent_Turret.auth_weapons ? "Yes" : "No"]", -"[Parent_Turret.check_records ? "Yes" : "No"]", -"[Parent_Turret.criminals ? "Yes" : "No"]", -"[Parent_Turret.stun_all ? "Yes" : "No"]" , -"[Parent_Turret.check_anomalies ? "Yes" : "No"]" ) - else - dat += text({" -Automatic Portable Turret Installation

    -Status: []
    "}, - -"[Parent_Turret.on ? "On" : "Off"]" ) - - user << browse("Automatic Portable Turret Installation[dat]", "window=autosec") - onclose(user, "autosec") - return - -/obj/machinery/porta_turret_cover/attack_hand(mob/user as mob) - . = ..() - if (.) - return - var/dat - if(!(Parent_Turret.lasercolor)) - dat += text({" -Automatic Portable Turret Installation

    -Status: []
    -Behaviour controls are [Parent_Turret.locked ? "locked" : "unlocked"]"}, - -"[Parent_Turret.on ? "On" : "Off"]" ) - - if(!Parent_Turret.locked) - dat += text({"
    -Check for Weapon Authorization: []
    -Check Security Records: []
    -Neutralize Identified Criminals: []
    -Neutralize All Non-Security and Non-Command Personnel: []
    -Neutralize All Unidentified Life Signs: []
    "}, - -"[Parent_Turret.auth_weapons ? "Yes" : "No"]", -"[Parent_Turret.check_records ? "Yes" : "No"]", -"[Parent_Turret.criminals ? "Yes" : "No"]", -"[Parent_Turret.stun_all ? "Yes" : "No"]" , -"[Parent_Turret.check_anomalies ? "Yes" : "No"]" ) - else - if(istype(user,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - if(((Parent_Turret.lasercolor) == "b") && (istype(H.wear_suit, /obj/item/clothing/suit/redtag))) - return - if(((Parent_Turret.lasercolor) == "r") && (istype(H.wear_suit, /obj/item/clothing/suit/bluetag))) - return - dat += text({" -Automatic Portable Turret Installation

    -Status: []
    "}, - -"[Parent_Turret.on ? "On" : "Off"]" ) - - - - user << browse("Automatic Portable Turret Installation[dat]", "window=autosec") - onclose(user, "autosec") - return +/obj/machinery/porta_turret_cover/attack_hand(mob/user) + return Parent_Turret.attack_hand(user) /obj/machinery/porta_turret_cover/Topic(href, href_list) - if (..()) - return - usr.set_machine(src) - Parent_Turret.add_fingerprint(usr) - src.add_fingerprint(usr) - if ((href_list["power"]) && (Parent_Turret.allowed(usr))) - if(Parent_Turret.anchored) - if (Parent_Turret.on) - Parent_Turret.on=0 - else - Parent_Turret.on=1 - else - usr << "\red It has to be secured first!" + Parent_Turret.Topic(href, href_list, 1) // Calling another object's Topic requires that we claim to not have a window, otherwise BYOND's base proc will runtime. - updateUsrDialog() - return - - switch(href_list["operation"]) - if ("authweapon") - Parent_Turret.auth_weapons = !Parent_Turret.auth_weapons - if ("checkrecords") - Parent_Turret.check_records = !Parent_Turret.check_records - if ("shootcrooks") - Parent_Turret.criminals = !Parent_Turret.criminals - if("shootall") - Parent_Turret.stun_all = !Parent_Turret.stun_all - if("checkxenos") - Parent_Turret.check_anomalies = !Parent_Turret.check_anomalies - - updateUsrDialog() - - - -/obj/machinery/porta_turret_cover/attackby(obj/item/W as obj, mob/user as mob) - - if ((istype(W, /obj/item/weapon/card/emag)) && (!Parent_Turret.emagged)) - user << "\red You short out [Parent_Turret]'s threat assessment circuits." - spawn(0) - for(var/mob/O in hearers(Parent_Turret, null)) - O.show_message("\red [Parent_Turret] hums oddly...", 1) - Parent_Turret.emagged = 1 - Parent_Turret.on = 0 - sleep(40) - Parent_Turret.on = 1 - - else if((istype(W, /obj/item/weapon/wrench)) && (!Parent_Turret.on)) - if(Parent_Turret.raised) return - - if(!Parent_Turret.anchored) - Parent_Turret.anchored = 1 - Parent_Turret.invisibility = INVISIBILITY_LEVEL_TWO - Parent_Turret.icon_state = "grey_target_prism" - user << "You secure the exterior bolts on the turret." - else - Parent_Turret.anchored = 0 - user << "You unsecure the exterior bolts on the turret." - Parent_Turret.icon_state = "turretCover" - Parent_Turret.invisibility = 0 - del(src) - - else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) - if (Parent_Turret.allowed(user)) - Parent_Turret.locked = !Parent_Turret.locked - user << "Controls are now [Parent_Turret.locked ? "locked." : "unlocked."]" - updateUsrDialog() - else - user << "\red Access denied." - - else - Parent_Turret.health -= W.force * 0.5 - if (Parent_Turret.health <= 0) - Parent_Turret.die() - if ((W.force * 0.5) > 2) - if(!Parent_Turret.attacked && !Parent_Turret.emagged) - Parent_Turret.attacked = 1 - spawn() - sleep(30) - Parent_Turret.attacked = 0 - ..() - - - - -/obj/machinery/porta_turret/stationary - emagged = 1 - - New() - installation = new/obj/item/weapon/gun/energy/laser(src.loc) - ..() +/obj/machinery/porta_turret_cover/attackby(obj/item/I, mob/user) + Parent_Turret.attackby(I, user) diff --git a/code/game/machinery/programmable_unloader.dm b/code/game/machinery/programmable_unloader.dm index c481d6fa32c..291b5849d2f 100644 --- a/code/game/machinery/programmable_unloader.dm +++ b/code/game/machinery/programmable_unloader.dm @@ -144,7 +144,7 @@ /obj/machinery/programmable/Topic(href, href_list) if(..()) - return + return 1 usr.set_machine(src) add_fingerprint(usr) switch(href_list["operation"]) @@ -195,20 +195,7 @@ updateUsrDialog() return -/obj/machinery/programmable/attackby(obj/item/I as obj, mob/user as mob) - if(istype(I,/obj/item/weapon/card/emag)) - if(emagged) - return - user << "You swipe the unloader with your card. After a moment's grinding, it beeps in a sinister fashion." - playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) - emagged = 1 - overrides += emag_overrides - - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(2, 1, src) - s.start() - - return +/obj/machinery/programmable/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I,/obj/item/weapon/wrench)) // code borrowed from pipe dispenser if (unwrenched==0) playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) @@ -281,7 +268,18 @@ I.loc = src RefreshParts() +/obj/machinery/programmable/emag_act(user as mob) + if(emagged) + return + user << "You swipe the unloader with your card. After a moment's grinding, it beeps in a sinister fashion." + playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) + emagged = 1 + overrides += emag_overrides + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 1, src) + s.start() + return /obj/machinery/programmable/process() if (!output || !input) @@ -512,7 +510,7 @@ return playsound(loc, "punch", 25, 1, -1) - if(M_HULK in H.mutations) damage += 5 + if(HULK in H.mutations) damage += 5 if(damage < 5) visible_message("[H] gives \the [src] a weak punch.") @@ -582,7 +580,7 @@ ..() resetlists() - attackby(obj/item/I as obj, mob/user as mob) + attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I,/obj/item/device/multitool)) hacking = (hacking?0:1) if(hacking) diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 758b76814ab..8f79948d09c 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -13,7 +13,7 @@ var/icon_state_charging = "recharger1" var/icon_state_idle = "recharger0" -/obj/machinery/recharger/attackby(obj/item/weapon/G as obj, mob/user as mob) +/obj/machinery/recharger/attackby(obj/item/weapon/G as obj, mob/user as mob, params) if(istype(user,/mob/living/silicon)) return if(istype(G, /obj/item/weapon/gun/energy) || istype(G, /obj/item/weapon/melee/baton) || istype(G,/obj/item/device/laptop)) diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index eea611886da..6b26c084997 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -19,17 +19,20 @@ component_parts += new /obj/item/weapon/stock_parts/capacitor(src) component_parts += new /obj/item/weapon/stock_parts/capacitor(src) component_parts += new /obj/item/weapon/stock_parts/manipulator(src) - component_parts += new /obj/item/weapon/cell/high(src) + component_parts += new /obj/item/weapon/stock_parts/cell/high(src) RefreshParts() build_icon() /obj/machinery/recharge_station/upgraded/New() ..() + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/cyborgrecharger(src) component_parts += new /obj/item/weapon/stock_parts/capacitor/super(src) component_parts += new /obj/item/weapon/stock_parts/capacitor/super(src) component_parts += new /obj/item/weapon/stock_parts/manipulator/pico(src) - component_parts += new /obj/item/weapon/cell/hyper(src) + component_parts += new /obj/item/weapon/stock_parts/cell/hyper(src) RefreshParts() + build_icon() /obj/machinery/recharge_station/RefreshParts() recharge_speed = 0 @@ -38,7 +41,7 @@ recharge_speed += C.rating * 100 for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) repairs += M.rating - 1 - for(var/obj/item/weapon/cell/C in component_parts) + for(var/obj/item/weapon/stock_parts/cell/C in component_parts) recharge_speed *= C.maxcharge / 10000 /obj/machinery/recharge_station/process() @@ -76,7 +79,7 @@ else icon_state = "borgcharger0" -/obj/machinery/recharge_station/attackby(obj/item/P as obj, mob/user as mob) +/obj/machinery/recharge_station/attackby(obj/item/P as obj, mob/user as mob, params) if (istype(P, /obj/item/weapon/screwdriver)) if(src.occupant) user << "The maintenance panel is locked." diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm index 27e46c668b5..3cc7919424b 100644 --- a/code/game/machinery/recycler.dm +++ b/code/game/machinery/recycler.dm @@ -31,14 +31,8 @@ var/const/SAFETY_COOLDOWN = 100 update_icon() -/obj/machinery/recycler/attackby(var/obj/item/I, var/mob/user) - if(istype(I, /obj/item/weapon/card/emag) && !emagged) - emagged = 1 - if(safety_mode) - safety_mode = 0 - update_icon() - playsound(src.loc, "sparks", 75, 1, -1) - else if(istype(I, /obj/item/weapon/screwdriver) && emagged) +/obj/machinery/recycler/attackby(var/obj/item/I, var/mob/user, params) + if(istype(I, /obj/item/weapon/screwdriver) && emagged) emagged = 0 update_icon() user << "You reset the crusher to its default factory settings." @@ -46,6 +40,14 @@ var/const/SAFETY_COOLDOWN = 100 ..() return add_fingerprint(user) + +/obj/machinery/recycler/emag_act(user as mob) + if(!emagged) + emagged = 1 + if(safety_mode) + safety_mode = 0 + update_icon() + playsound(src.loc, "sparks", 75, 1, -1) /obj/machinery/recycler/update_icon() ..() @@ -138,7 +140,7 @@ var/const/SAFETY_COOLDOWN = 100 // Remove and recycle the equipped items. for(var/obj/item/I in L.get_equipped_items()) - if(L.u_equip(I)) + if(L.unEquip(I)) recycle(I, 0) // Instantly lie down, also go unconscious from the pain, before you die. diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index d358e39c67f..ed6e201a3ff 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -55,6 +55,7 @@ var/list/obj/machinery/requests_console/allConsoles = list() var/dpt = ""; //the department which will be receiving the message var/priority = -1 ; //Priority of the message being sent luminosity = 0 + var/datum/announcement/announcement = new /obj/machinery/requests_console/power_change() ..() @@ -70,6 +71,10 @@ var/list/obj/machinery/requests_console/allConsoles = list() /obj/machinery/requests_console/New() ..() + + announcement.title = "[department] announcement" + announcement.newscast = 1 + name = "[department] Requests Console" allConsoles += src //req_console_departments += department @@ -189,7 +194,7 @@ var/list/obj/machinery/requests_console/allConsoles = list() else //main menu screen = 0 - announceAuth = 0 + reset_announce() if (newmessagepriority == 1) dat += text("There are new messages
    ") if (newmessagepriority == 2) @@ -240,17 +245,13 @@ var/list/obj/machinery/requests_console/allConsoles = list() if("2") priority = 2 else priority = -1 else - message = "" - announceAuth = 0 + reset_announce() screen = 0 if(href_list["sendAnnouncement"]) if(!announcementConsole) return - for(var/mob/M in player_list) - if(!istype(M,/mob/new_player)) - M << "[department] announcement: [message]" - announceAuth = 0 - message = "" + announcement.Announce(message) + reset_announce() screen = 0 if( href_list["department"] && message ) @@ -357,7 +358,7 @@ var/list/obj/machinery/requests_console/allConsoles = list() return //err... hacking code, which has no reason for existing... but anyway... it's supposed to unlock priority 3 messanging on that console (EXTREME priority...) the code for that actually exists. -/obj/machinery/requests_console/attackby(var/obj/item/weapon/O as obj, var/mob/user as mob) +/obj/machinery/requests_console/attackby(var/obj/item/weapon/O as obj, var/mob/user as mob, params) /* if (istype(O, /obj/item/weapon/crowbar)) if(open) @@ -389,8 +390,9 @@ var/list/obj/machinery/requests_console/allConsoles = list() var/obj/item/weapon/card/id/ID = O if (access_RC_announce in ID.GetAccess()) announceAuth = 1 + announcement.announcer = ID.assignment ? "[ID.assignment] [ID.registered_name]" : ID.registered_name else - announceAuth = 0 + reset_announce() user << "\red You are not authorized to send announcements." updateUsrDialog() if (istype(O, /obj/item/weapon/stamp)) @@ -399,3 +401,8 @@ var/list/obj/machinery/requests_console/allConsoles = list() msgStamped = text("Stamped with the [T.name]") updateUsrDialog() return + +/obj/machinery/requests_console/proc/reset_announce() + announceAuth = 0 + message = "" + announcement.announcer = "" diff --git a/code/game/machinery/robot_fabricator.dm b/code/game/machinery/robot_fabricator.dm index 65f31c94c0d..504f7ef8956 100644 --- a/code/game/machinery/robot_fabricator.dm +++ b/code/game/machinery/robot_fabricator.dm @@ -11,7 +11,7 @@ idle_power_usage = 20 active_power_usage = 5000 -/obj/machinery/robotic_fabricator/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/machinery/robotic_fabricator/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if (istype(O, /obj/item/stack/sheet/metal)) if (src.metal_amount < 150000.0) var/count = 0 diff --git a/code/game/machinery/seed_extractor.dm b/code/game/machinery/seed_extractor.dm index dbb5a9d2712..f2e45ccdc41 100644 --- a/code/game/machinery/seed_extractor.dm +++ b/code/game/machinery/seed_extractor.dm @@ -6,7 +6,7 @@ density = 1 anchored = 1 -obj/machinery/seed_extractor/attackby(var/obj/item/O as obj, var/mob/user as mob) +obj/machinery/seed_extractor/attackby(var/obj/item/O as obj, var/mob/user as mob, params) // Fruits and vegetables. if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown) || istype(O, /obj/item/weapon/grown)) diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index e6225f648d7..07570114f00 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -25,16 +25,7 @@ if(!height || air_group) return 0 else return ..() -//Looks like copy/pasted code... I doubt 'need_rebuild' is even used here - Nodrak -/obj/machinery/shield/proc/update_nearby_tiles(need_rebuild) - if(!air_master) return 0 - - air_master.mark_for_update(get_turf(src)) - - return 1 - - -/obj/machinery/shield/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/shield/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(!istype(W)) return //Calculate damage @@ -47,7 +38,7 @@ if (src.health <= 0) - visible_message("\blue The [src] dissapates") + visible_message("\blue The [src] dissipates") del(src) return @@ -60,7 +51,7 @@ src.health -= max_health*0.75 //3/4 health as damage if(src.health <= 0) - visible_message("\blue The [src] dissapates") + visible_message("\blue The [src] dissipates") del(src) return @@ -72,7 +63,7 @@ health -= Proj.damage ..() if(health <=0) - visible_message("\blue The [src] dissapates") + visible_message("\blue The [src] dissipates") del(src) return opacity = 1 @@ -121,7 +112,7 @@ //Handle the destruction of the shield if (src.health <= 0) - visible_message("\blue The [src] dissapates") + visible_message("\blue The [src] dissipates") del(src) return @@ -250,7 +241,7 @@ user << "The device must first be secured to the floor." return -/obj/machinery/shieldgen/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/shieldgen/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/card/emag)) malfunction = 1 update_icon() @@ -335,7 +326,7 @@ // var/maxshieldload = 200 var/obj/structure/cable/attached // the attached cable var/storedpower = 0 - flags = FPRINT | CONDUCT + flags = CONDUCT use_power = 0 /obj/machinery/shieldwallgen/proc/power() @@ -470,7 +461,7 @@ CF.dir = field_dir -/obj/machinery/shieldwallgen/attackby(obj/item/W, mob/user) +/obj/machinery/shieldwallgen/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/weapon/wrench)) if(active) user << "Turn off the field generator first." @@ -498,8 +489,8 @@ user << "\red Access denied." else - src.add_fingerprint(user) - visible_message("\red The [src.name] has been hit with the [W.name] by [user.name]!") + add_fingerprint(user) + ..() /obj/machinery/shieldwallgen/proc/cleanup(var/NSEW) var/obj/machinery/shieldwall/F diff --git a/code/game/machinery/slotmachine.dm b/code/game/machinery/slotmachine.dm index d2d93afba2c..54355179c8e 100644 --- a/code/game/machinery/slotmachine.dm +++ b/code/game/machinery/slotmachine.dm @@ -1,3 +1,4 @@ +var/datum/announcement/minor/slotmachine_announcement = new(do_log = 0) /obj/machinery/slot_machine name = "Slot Machine" desc = "Gambling for the antisocial." @@ -55,7 +56,7 @@ if (roll == 1) for(var/mob/O in hearers(src, null)) O.show_message(text("[] says, 'JACKPOT! You win [src.money]!'", src), 1) - command_alert("Congratulations [usr.name] on winning the Jackpot!", "Jackpot Winner") + slotmachine_announcement.Announce("Congratulations [usr.name] on winning the Jackpot!", "Jackpot Winner") usr.mind.initial_account.money += src.money src.money = 0 else if (roll > 1 && roll <= 10) diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index 9a6849dcdf4..9877ac6f138 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -5,13 +5,12 @@ icon_state = "sheater0" name = "space heater" desc = "Made by Space Amish using traditional space techniques, this heater is guaranteed not to set the station on fire." - var/obj/item/weapon/cell/cell + var/obj/item/weapon/stock_parts/cell/cell var/on = 0 var/open = 0 var/set_temperature = 50 // in celcius, add T0C for kelvin var/heating_power = 40000 - flags = FPRINT New() @@ -51,15 +50,15 @@ cell.emp_act(severity) ..(severity) - attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/weapon/cell)) + attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/weapon/stock_parts/cell)) if(open) if(cell) user << "There is already a power cell inside." return else // insert cell - var/obj/item/weapon/cell/C = usr.get_active_hand() + var/obj/item/weapon/stock_parts/cell/C = usr.get_active_hand() if(istype(C)) user.drop_item() cell = C @@ -120,8 +119,8 @@ Topic(href, href_list) - if (usr.stat) - return + if (..()) + return 1 if ((in_range(src, usr) && istype(src.loc, /turf)) || (istype(usr, /mob/living/silicon))) usr.set_machine(src) @@ -144,7 +143,7 @@ if("cellinstall") if(open && !cell) - var/obj/item/weapon/cell/C = usr.get_active_hand() + var/obj/item/weapon/stock_parts/cell/C = usr.get_active_hand() if(istype(C)) usr.drop_item() cell = C diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 0b81ccabbeb..66c26a8b654 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -153,7 +153,7 @@ /obj/machinery/suit_storage_unit/Topic(href, href_list) //I fucking HATE this proc if(..()) - return + return 1 if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon/ai))) usr.set_machine(src) if (href_list["toggleUV"]) @@ -470,7 +470,7 @@ return -/obj/machinery/suit_storage_unit/attackby(obj/item/I as obj, mob/user as mob) +/obj/machinery/suit_storage_unit/attackby(obj/item/I as obj, mob/user as mob, params) if(!src.ispowered) return if(istype(I, /obj/item/weapon/screwdriver)) @@ -631,7 +631,7 @@ user << "\blue The console controls are far too complicated for your tiny brain!" return -/obj/machinery/suit_cycler/attackby(obj/item/I as obj, mob/user as mob) +/obj/machinery/suit_cycler/attackby(obj/item/I as obj, mob/user as mob, params) if(electrified != 0) if(src.shock(user, 100)) @@ -681,24 +681,6 @@ src.updateUsrDialog() return - else if(istype(I,/obj/item/weapon/card/emag)) - - if(emagged) - user << "\red The cycler has already been subverted." - return - - var/obj/item/weapon/card/emag/E = I - src.updateUsrDialog() - E.uses-- - - //Clear the access reqs, disable the safeties, and open up all paintjobs. - user << "\red You run the sequencer across the interface, corrupting the operating protocols." - departments = list("Engineering","Mining","Medical","Security","Atmos","^%###^%$") - emagged = 1 - safeties = 0 - req_access = list() - return - else if(istype(I,/obj/item/clothing/head/helmet/space)) if(locked) @@ -748,6 +730,19 @@ return ..() + +/obj/machinery/suit_cycler/emag_act(user as mob) + if(emagged) + user << "\red The cycler has already been subverted." + return + + //Clear the access reqs, disable the safeties, and open up all paintjobs. + user << "\red You run the sequencer across the interface, corrupting the operating protocols." + departments = list("Engineering","Mining","Medical","Security","Atmos","^%###^%$") + emagged = 1 + safeties = 0 + req_access = list() + return /obj/machinery/suit_cycler/attack_hand(mob/user as mob) diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm index a4cc791bff9..916ae1a23af 100644 --- a/code/game/machinery/syndicatebeacon.dm +++ b/code/game/machinery/syndicatebeacon.dm @@ -39,6 +39,8 @@ onclose(user, "syndbeacon") Topic(href, href_list) + if(..()) + return 1 if(href_list["betraitor"]) if(charges < 1) src.updateUsrDialog() @@ -154,7 +156,7 @@ return - attackby(obj/item/weapon/W as obj, mob/user as mob) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/screwdriver)) if(active) user << "\red You need to deactivate the beacon first!" diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index fcce1742ff9..314f14e0ffa 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -48,7 +48,7 @@ /obj/machinery/syndicatebomb/update_icon() icon_state = "[initial(icon_state)][active ? "-active" : "-inactive"][open_panel ? "-wires" : ""]" -/obj/machinery/syndicatebomb/attackby(var/obj/item/I, var/mob/user) +/obj/machinery/syndicatebomb/attackby(var/obj/item/I, var/mob/user, params) if(istype(I, /obj/item/weapon/wrench)) if(!anchored) if(!isturf(src.loc) || istype(src.loc, /turf/space)) @@ -138,7 +138,7 @@ var/turf/bombturf = get_turf(src) var/area/A = get_area(bombturf) if(payload && !istype(payload, /obj/item/weapon/bombcore/training)) - message_admins("[key_name(user)]? has primed a [name] ([payload]) for detonation at [A.name] (JMP).") + msg_admin_attack("[key_name(user)]? has primed a [name] ([payload]) for detonation at [A.name] (JMP).") log_game("[key_name(user)] has primed a [name] ([payload]) for detonation at [A.name]([bombturf.x],[bombturf.y],[bombturf.z])") payload.adminlog = "The [src.name] that [key_name(user)] had primed detonated!" diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm index d2dbe48ce03..995bfe7afac 100644 --- a/code/game/machinery/telecomms/broadcaster.dm +++ b/code/game/machinery/telecomms/broadcaster.dm @@ -20,7 +20,6 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept use_power = 1 idle_power_usage = 25 machinetype = 5 - heatgen = 0 delay = 7 circuitboard = "/obj/item/weapon/circuitboard/telecomms/broadcaster" @@ -59,7 +58,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 +85,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 @@ -95,7 +97,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept /* --- Do a snazzy animation! --- */ flick("broadcaster_send", src) -/obj/machinery/telecomms/broadcaster/Destroy() +/obj/machinery/telecomms/broadcaster/Del() // In case message_delay is left on 1, otherwise it won't reset the list and people can't say the same thing twice anymore. if(message_delay) message_delay = 0 @@ -117,7 +119,6 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept use_power = 0 idle_power_usage = 0 machinetype = 6 - heatgen = 0 var/intercept = 0 // if nonzero, broadcasts all messages to syndicate channel /obj/machinery/telecomms/allinone/receive_signal(datum/signal/signal) @@ -142,19 +143,21 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept var/datum/radio_frequency/connection = signal.data["connection"] - if(connection.frequency == SYND_FREQ) // if syndicate broadcast, just + if(connection.frequency in ANTAG_FREQS) // if antag broadcast, just 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"],, 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 +221,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 ###### */ @@ -246,16 +250,14 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept if(R.receive_range(display_freq, level) > -1) radios += R - // --- Broadcast to syndicate radio! --- + // --- Broadcast to antag radios! --- else if(data == 3) - - var/datum/radio_frequency/syndicateconnection = radio_controller.return_frequency(SYND_FREQ) - - for (var/obj/item/device/radio/R in syndicateconnection.devices["[RADIO_CHAT]"]) - - if(R.receive_range(SYND_FREQ, level) > -1) - radios += R + for(var/antag_freq in ANTAG_FREQS) + var/datum/radio_frequency/antag_connection = radio_controller.return_frequency(antag_freq) + for (var/obj/item/device/radio/R in antag_connection.devices["[RADIO_CHAT]"]) + if(R.receive_range(antag_freq, level) > -1) + radios += R // --- Broadcast to ALL radio devices --- @@ -283,6 +285,8 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept /* --- Loop through the receivers and categorize them --- */ + if (R.client && !(R.client.prefs.toggles & CHAT_RADIO)) //Adminning with 80 people on can be fun when you're trying to talk and all you can hear is radios. + continue if(istype(R, /mob/new_player)) // we don't want new players to hear messages. rare but generates runtimes. continue @@ -324,88 +328,17 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept if (length(heard_masked) || length(heard_normal) || length(heard_voice) || length(heard_garbled) || length(heard_gibberish)) /* --- Some miscellaneous variables to format the string output --- */ - var/part_a = "" // goes in the actual output - var/freq_text // the name of the channel - - // --- Set the name of the channel --- - switch(display_freq) - - if(SYND_FREQ) - freq_text = "#unkn" - if(COMM_FREQ) - freq_text = "Command" - if(1351) - freq_text = "Science" - if(1355) - freq_text = "Medical" - if(1357) - freq_text = "Engineering" - if(1359) - freq_text = "Security" - if(1347) - freq_text = "Supply" - if(1349) - freq_text = "Service" - if(1441) - freq_text = "Special Ops" - if(1443) - freq_text = "Response Team" - if(1447) - freq_text = "AI Private" - //There's probably a way to use the list var of channels in code\game\communications.dm to make the dept channels non-hardcoded, but I wasn't in an experimentive mood. --NEO - - - // --- If the frequency has not been assigned a name, just use the frequency as the name --- - - if(!freq_text) - freq_text = format_frequency(display_freq) - - // --- Some more pre-message formatting --- + var/freq_text = get_frequency_name(display_freq) var/part_b_extra = "" if(data == 3) // intercepted radio message part_b_extra = " (Intercepted)" - var/part_b = " \icon[radio]\[[freq_text]\][part_b_extra] " // Tweaked for security headsets -- TLE + var/part_a = "\icon[radio]\[[freq_text]\][part_b_extra] " // goes in the actual output + + // --- Some more pre-message formatting --- + var/part_b = " " // Tweaked for security headsets -- TLE var/part_c = "" - // syndies! - if (display_freq == SYND_FREQ) - part_a = "" - - // centcomm channels (deathsquid and ert) - else if (display_freq in CENT_FREQS) - part_a = "" - - // command channel - else if (display_freq == COMM_FREQ) - part_a = "" - - // AI private channel - else if (display_freq == 1447) - part_a = "" - - // department radio formatting (poorly optimized, ugh) - else if (display_freq == SEC_FREQ) - part_a = "" - - else if (display_freq == ENG_FREQ) - part_a = "" - - else if (display_freq == SCI_FREQ) - part_a = "" - - else if (display_freq == MED_FREQ) - part_a = "" - - else if (display_freq == SUP_FREQ) // cargo - part_a = "" - - else if (display_freq == SRV_FREQ) // cargo - part_a = "" - // If all else fails and it's a dept_freq, color me purple! - else if (display_freq in DEPT_FREQS) - part_a = "" - // --- Filter the message; place it in quotes apply a verb --- @@ -424,133 +357,67 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept //BR.messages_admin += blackbox_admin_msg if(istype(blackbox)) switch(display_freq) - if(1459) + if(PUB_FREQ) blackbox.msg_common += blackbox_msg - if(1351) + if(SCI_FREQ) blackbox.msg_science += blackbox_msg - if(1353) + if(COMM_FREQ) blackbox.msg_command += blackbox_msg - if(1355) + if(MED_FREQ) blackbox.msg_medical += blackbox_msg - if(1357) + if(ENG_FREQ) blackbox.msg_engineering += blackbox_msg - if(1359) + if(SEC_FREQ) blackbox.msg_security += blackbox_msg - if(1441) + if(DTH_FREQ) blackbox.msg_deathsquad += blackbox_msg - if(1213) + if(SYND_FREQ) blackbox.msg_syndicate += blackbox_msg - if(1347) + if(SUP_FREQ) blackbox.msg_cargo += blackbox_msg - if(1349) + if(SRV_FREQ) blackbox.msg_service += blackbox_msg else blackbox.messages += blackbox_msg //End of research and feedback code. - var/aitrack = "" - var/aiopen = "" /* ###### 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 = "" - aiopen = "\[OPEN\] " - if(data == 4) - aitrack = "" - - if(istype(R, /mob/living/silicon/ai)) - R.show_message("[part_a][aitrack][N] ([J]) [aiopen][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 = "" - aiopen = "\[OPEN\] " - if(data == 4) - aitrack = "" - - if(istype(R, /mob/living/silicon/ai)) - R.show_message("[part_a][aitrack][realname] ([job]) [aiopen][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 = "" - aiopen = "\[OPEN\] " - if(data == 4) - aitrack = "" - - - if(istype(R, /mob/living/silicon/ai)) - R.show_message("[part_a][aitrack][vname] ([job]) [aiopen][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 = "" - aiopen = "\[OPEN\] " - if(data == 4) - aitrack = "" - - - if(istype(R, /mob/living/silicon/ai)) - R.show_message("[part_a][aitrack][vname][aiopen][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 = "" - aiopen = "\[OPEN\] " - 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)]) [aiopen][part_b][quotedmsg][part_c]", 2) - else - R.show_message(rendered, 2) - + R.hear_radio(message, verbage, speaking, part_a, part_b, M, 1) + return 1 /proc/Broadcast_SimpleMessage(var/source, var/frequency, var/text, var/data, var/mob/M, var/compression, var/level) @@ -588,15 +455,15 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept receive |= R.send_hear(display_freq) - // --- Broadcast to syndicate radio! --- + // --- Broadcast to antag radios! --- else if(data == 3) - var/datum/radio_frequency/syndicateconnection = radio_controller.return_frequency(SYND_FREQ) - - for (var/obj/item/device/radio/R in syndicateconnection.devices["[RADIO_CHAT]"]) - var/turf/position = get_turf(R) - if(position && position.z == level) - receive |= R.send_hear(SYND_FREQ) + for(var/freq in ANTAG_FREQS) + var/datum/radio_frequency/antag_connection = radio_controller.return_frequency(freq) + for (var/obj/item/device/radio/R in antag_connection.devices["[RADIO_CHAT]"]) + var/turf/position = get_turf(R) + if(position && position.z == level) + receive |= R.send_hear(freq) // --- Broadcast to ALL radio devices --- @@ -621,6 +488,8 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept /* --- Loop through the receivers and categorize them --- */ + if (R.client && !(R.client.prefs.toggles & CHAT_RADIO)) //Adminning with 80 people on can be fun when you're trying to talk and all you can hear is radios. + continue // --- Check for compression --- @@ -648,34 +517,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept /* --- Some miscellaneous variables to format the string output --- */ var/part_a = "" // goes in the actual output - var/freq_text // the name of the channel - - // --- Set the name of the channel --- - switch(display_freq) - - if(SYND_FREQ) - freq_text = "#unkn" - if(COMM_FREQ) - freq_text = "Command" - if(1351) - freq_text = "Science" - if(1355) - freq_text = "Medical" - if(1357) - freq_text = "Engineering" - if(1359) - freq_text = "Security" - if(1347) - freq_text = "Supply" - if(1349) - freq_text = "Service" - //There's probably a way to use the list var of channels in code\game\communications.dm to make the dept channels non-hardcoded, but I wasn't in an experimentive mood. --NEO - - - // --- If the frequency has not been assigned a name, just use the frequency as the name --- - - if(!freq_text) - freq_text = format_frequency(display_freq) + var/freq_text = get_frequency_name(display_freq) // --- Some more pre-message formatting --- @@ -689,7 +531,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept var/part_b = " \icon[radio]\[[freq_text]\][part_b_extra] " // Tweaked for security headsets -- TLE var/part_c = "" - if (display_freq==SYND_FREQ) + if (display_freq in ANTAG_FREQS) part_a = "" else if (display_freq==COMM_FREQ) part_a = "" @@ -705,25 +547,25 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept //BR.messages_admin += blackbox_admin_msg if(istype(blackbox)) switch(display_freq) - if(1459) + if(PUB_FREQ) blackbox.msg_common += blackbox_msg - if(1351) + if(SCI_FREQ) blackbox.msg_science += blackbox_msg - if(1353) + if(COMM_FREQ) blackbox.msg_command += blackbox_msg - if(1355) + if(MED_FREQ) blackbox.msg_medical += blackbox_msg - if(1357) + if(ENG_FREQ) blackbox.msg_engineering += blackbox_msg - if(1359) + if(SEC_FREQ) blackbox.msg_security += blackbox_msg - if(1441) + if(DTH_FREQ) blackbox.msg_deathsquad += blackbox_msg - if(1213) + if(SYND_FREQ) blackbox.msg_syndicate += blackbox_msg - if(1347) + if(SUP_FREQ) blackbox.msg_cargo += blackbox_msg - if(1349) + if(SRV_FREQ) blackbox.msg_service += blackbox_msg else blackbox.messages += blackbox_msg @@ -767,7 +609,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept var/turf/position = get_turf(src) return (position.z in signal.data["level"] && signal.data["done"]) -/atom/proc/telecomms_process() +/atom/proc/telecomms_process(var/do_sleep = 1) // First, we want to generate a new radio signal var/datum/signal/signal = new @@ -785,13 +627,14 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept "done" = 0, "level" = pos.z // The level it is being broadcasted at. ) - signal.frequency = 1459// Common channel + signal.frequency = PUB_FREQ// Common channel //#### Sending the signal to all subspace receivers ####// for(var/obj/machinery/telecomms/receiver/R in telecomms_list) R.receive_signal(signal) - sleep(rand(10,25)) + if(do_sleep) + sleep(rand(10,25)) //world.log << "Level: [signal.data["level"]] - Done: [signal.data["done"]]" diff --git a/code/game/machinery/telecomms/logbrowser.dm b/code/game/machinery/telecomms/logbrowser.dm index 9bd46e57ce7..2fb2cd3cc69 100644 --- a/code/game/machinery/telecomms/logbrowser.dm +++ b/code/game/machinery/telecomms/logbrowser.dm @@ -217,7 +217,7 @@ updateUsrDialog() return - attackby(var/obj/item/weapon/D as obj, var/mob/user as mob) + attackby(var/obj/item/weapon/D as obj, var/mob/user as mob, params) if(istype(D, /obj/item/weapon/screwdriver)) playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) if(do_after(user, 20)) @@ -244,9 +244,11 @@ A.icon_state = "4" A.anchored = 1 del(src) - else if(istype(D, /obj/item/weapon/card/emag) && !emagged) + src.updateUsrDialog() + return + + emag_act(user as mob) + if(!emagged) playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) emagged = 1 user << "\blue You you disable the security protocols" - src.updateUsrDialog() - return diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm index af05db47db6..55a4e604e0f 100644 --- a/code/game/machinery/telecomms/machine_interactions.dm +++ b/code/game/machinery/telecomms/machine_interactions.dm @@ -13,7 +13,7 @@ var/construct_op = 0 -/obj/machinery/telecomms/attackby(obj/item/P as obj, mob/user as mob) +/obj/machinery/telecomms/attackby(obj/item/P as obj, mob/user as mob, params) // Using a multitool lets you access the receiver's interface if(istype(P, /obj/item/device/multitool)) diff --git a/code/game/machinery/telecomms/presets.dm b/code/game/machinery/telecomms/presets.dm index c1bc006e4b3..5d14fc2f9bc 100644 --- a/code/game/machinery/telecomms/presets.dm +++ b/code/game/machinery/telecomms/presets.dm @@ -29,7 +29,7 @@ hide = 1 toggled = 1 //anchored = 1 - //use_power = 0 + use_power = 0 //idle_power_usage = 0 heatgen = 0 autolinkers = list("c_relay") @@ -42,6 +42,13 @@ autolinkers = list("hub", "relay", "c_relay", "s_relay", "m_relay", "r_relay", "science", "medical", "supply", "service", "common", "command", "engineering", "security", "receiverA", "receiverB", "broadcasterA", "broadcasterB") + +/obj/machinery/telecomms/hub/preset_cent + id = "CentComm Hub" + network = "tcommsat" + use_power = 0 + autolinkers = list("hub_cent", "c_relay", "s_relay", "m_relay", "r_relay", + "centcomm", "receiverCent", "broadcasterCent") //Receivers @@ -67,7 +74,13 @@ for(var/i = 1441, i < 1489, i += 2) freq_listening |= i ..() - + +/obj/machinery/telecomms/receiver/preset_cent + id = "CentComm Receiver" + network = "tcommsat" + use_power = 0 + autolinkers = list("receiverCent") + freq_listening = list(ERT_FREQ, DTH_FREQ) //Buses @@ -99,6 +112,13 @@ for(var/i = 1441, i < 1489, i += 2) freq_listening |= i ..() + +/obj/machinery/telecomms/bus/preset_cent + id = "CentComm Bus" + network = "tcommsat" + use_power = 0 + freq_listening = list(ERT_FREQ, DTH_FREQ) + autolinkers = list("processorCent", "centcomm") //Processors @@ -121,6 +141,12 @@ id = "Processor 4" network = "tcommsat" autolinkers = list("processor4") + +/obj/machinery/telecomms/processor/preset_cent + id = "CentComm Processor" + network = "tcommsat" + use_power = 0 + autolinkers = list("processorCent") //Servers @@ -175,6 +201,11 @@ freq_listening = list(1359) autolinkers = list("security") +/obj/machinery/telecomms/server/presets/centcomm + id = "CentComm Server" + freq_listening = list(ERT_FREQ, DTH_FREQ) + use_power = 0 + autolinkers = list("centcomm") //Broadcasters @@ -191,3 +222,9 @@ id = "Broadcaster B" network = "tcommsat" autolinkers = list("broadcasterB") + +/obj/machinery/telecomms/broadcaster/preset_cent + id = "CentComm Broadcaster" + network = "tcommsat" + use_power = 0 + autolinkers = list("broadcasterCent") \ No newline at end of file diff --git a/code/game/machinery/telecomms/telemonitor.dm b/code/game/machinery/telecomms/telemonitor.dm index 995d0fc239f..23969177606 100644 --- a/code/game/machinery/telecomms/telemonitor.dm +++ b/code/game/machinery/telecomms/telemonitor.dm @@ -126,7 +126,7 @@ updateUsrDialog() return - attackby(var/obj/item/weapon/D as obj, var/mob/user as mob) + attackby(var/obj/item/weapon/D as obj, var/mob/user as mob, params) if(istype(D, /obj/item/weapon/screwdriver)) playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) if(do_after(user, 20)) @@ -153,9 +153,11 @@ A.icon_state = "4" A.anchored = 1 del(src) - else if(istype(D, /obj/item/weapon/card/emag) && !emagged) - playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) - emagged = 1 - user << "\blue You you disable the security protocols" src.updateUsrDialog() return + + emag_act(user as mob) + if(!emagged) + playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) + emagged = 1 + user << "\blue You you disable the security protocols" \ No newline at end of file diff --git a/code/game/machinery/telecomms/traffic_control.dm b/code/game/machinery/telecomms/traffic_control.dm index fed56a35124..889623b60e6 100644 --- a/code/game/machinery/telecomms/traffic_control.dm +++ b/code/game/machinery/telecomms/traffic_control.dm @@ -206,7 +206,7 @@ return -/obj/machinery/computer/telecomms/traffic/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob) +/obj/machinery/computer/telecomms/traffic/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob, params) if(istype(D, /obj/item/weapon/screwdriver)) playsound(get_turf(src), 'sound/items/Screwdriver.ogg', 50, 1) if(do_after(user, 20)) @@ -233,12 +233,14 @@ A.icon_state = "4" A.anchored = 1 del(src) - else if(istype(D, /obj/item/weapon/card/emag) && !emagged) + src.updateUsrDialog() + return + +/obj/machinery/computer/telecomms/traffic/emag_act(user as mob) + if(!emagged) playsound(get_turf(src), 'sound/effects/sparks4.ogg', 75, 1) emagged = 1 user << "\blue You you disable the security protocols" - src.updateUsrDialog() - return /obj/machinery/computer/telecomms/traffic/proc/canAccess(var/mob/user) if(issilicon(user) || in_range(user, src)) diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index 9e18e2ce265..9d30d7207af 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -30,20 +30,13 @@ break return power_station -/obj/machinery/computer/teleporter/attackby(I as obj, mob/living/user as mob) - if(istype(I,/obj/item/weapon/card/emag)) // If hit by an emag. - var/obj/item/weapon/card/emag/E = I - if(!emagged) - if(E.uses) - E.uses-- - emagged = 1 - user << "\blue The teleporter can now lock on to Syndicate beacons!" - else - ui_interact(user) - else if(istype(I, /obj/item/device/gps)) +/obj/machinery/computer/teleporter/attackby(I as obj, mob/living/user as mob, params) + if(istype(I, /obj/item/device/gps)) var/obj/item/device/gps/L = I if(L.locked_location && !(stat & (NOPOWER|BROKEN))) - user.before_take_item(L) + if(!user.unEquip(L)) + user << "\the [I] is stuck to your hand, you cannot put it in \the [src]" + return L.loc = src locked = L user << "You insert the GPS device into the [name]'s slot." @@ -53,6 +46,13 @@ else ..() return + +/obj/machinery/computer/teleporter/emag_act(user as mob) + if(!emagged) + emagged = 1 + user << "\blue The teleporter can now lock on to Syndicate beacons!" + else + ui_interact(user) /obj/machinery/computer/teleporter/attack_paw(mob/user) usr << "You are too primitive to use this computer." @@ -80,7 +80,8 @@ data["calibrated"] = null data["accurate"] = null data["regime"] = regime_set - data["target"] = (!target) ? "None" : get_area(target) + var/area/targetarea = get_area(target) + data["target"] = (!target) ? "None" : sanitize(targetarea.name) data["calibrating"] = calibrating data["locked"] = locked @@ -93,7 +94,7 @@ /obj/machinery/computer/teleporter/Topic(href, href_list) if(..()) - return + return 1 if(href_list["eject"]) eject() @@ -179,7 +180,7 @@ var/turf/T = get_turf(R) if (!T) continue - if(T.z == 2 || T.z > 7) + if((T.z in config.admin_levels) || T.z > 7) continue if(R.syndicate == 1 && emagged == 0) continue @@ -200,7 +201,7 @@ continue var/turf/T = get_turf(M) if(!T) continue - if(T.z == 2) continue + if((T.z in config.admin_levels)) continue var/tmpname = M.real_name if(areaindex[tmpname]) tmpname = "[tmpname] ([++areaindex[tmpname]])" @@ -222,7 +223,7 @@ var/turf/T = get_turf(R) if (!T || !R.teleporter_hub || !R.teleporter_console) continue - if(T.z == 2 || T.z > 7) + if((T.z in config.admin_levels) || T.z > 7) continue var/tmpname = T.loc.name if(areaindex[tmpname]) @@ -279,7 +280,7 @@ component_parts += new /obj/item/bluespace_crystal/artificial(null) component_parts += new /obj/item/weapon/stock_parts/matter_bin(null) RefreshParts() - + /obj/machinery/teleport/hub/upgraded/New() ..() component_parts = list() @@ -328,7 +329,7 @@ //--FalseIncarnate return -/obj/machinery/teleport/hub/attackby(obj/item/W, mob/user) +/obj/machinery/teleport/hub/attackby(obj/item/W, mob/user, params) if(default_deconstruction_screwdriver(user, "tele-o", "tele0", W)) return @@ -413,7 +414,7 @@ teleporter_hub.update_icon() ..() -/obj/machinery/teleport/station/attackby(var/obj/item/weapon/W, mob/user) +/obj/machinery/teleport/station/attackby(var/obj/item/weapon/W, mob/user, params) if(istype(W, /obj/item/device/multitool) && !panel_open) var/obj/item/device/multitool/M = W if(M.buffer && istype(M.buffer, /obj/machinery/teleport/station) && M.buffer != src) diff --git a/code/game/machinery/turret_control.dm b/code/game/machinery/turret_control.dm new file mode 100644 index 00000000000..83bd5b5217d --- /dev/null +++ b/code/game/machinery/turret_control.dm @@ -0,0 +1,221 @@ +//////////////////////// +//Turret Control Panel// +//////////////////////// + +/area + // Turrets use this list to see if individual power/lethal settings are allowed + var/list/turret_controls = list() + +/obj/machinery/turretid + name = "turret control panel" + desc = "Used to control a room's automated defenses." + icon = 'icons/obj/machines/turret_control.dmi' + icon_state = "control_standby" + anchored = 1 + density = 0 + var/enabled = 0 + var/lethal = 0 + var/locked = 1 + var/area/control_area //can be area name, path or nothing. + + var/check_arrest = 1 //checks if the perp is set to arrest + var/check_records = 1 //checks if a security record exists at all + var/check_weapons = 0 //checks if it can shoot people that have a weapon they aren't authorized to have + var/check_access = 1 //if this is active, the turret shoots everything that does not meet the access requirements + var/check_anomalies = 1 //checks if it can shoot at unidentified lifeforms (ie xenos) + var/check_synth = 0 //if active, will shoot at anything not an AI or cyborg + var/ailock = 0 //Silicons cannot use this + + req_access = list(access_ai_upload) + +/obj/machinery/turretid/stun + enabled = 1 + icon_state = "control_stun" + +/obj/machinery/turretid/lethal + enabled = 1 + lethal = 1 + icon_state = "control_kill" + +/obj/machinery/turretid/Del() + if(control_area) + var/area/A = control_area + if(A && istype(A)) + A.turret_controls -= src + ..() + +/obj/machinery/turretid/initialize() + if(!control_area) + var/area/CA = get_area(src) + control_area = CA.master + else if(istext(control_area)) + for(var/area/A in world) + if(A.name && A.name==control_area) + control_area = A.master + break + + if(control_area) + var/area/A = control_area + if(istype(A)) + A.turret_controls += src + else + control_area = null + + power_change() //Checks power and initial settings + return + +/obj/machinery/turretid/proc/isLocked(mob/user) + if(ailock && (isrobot(user) || isAI(user))) + user << "There seems to be a firewall preventing you from accessing this device." + return 1 + + if(locked && !(isrobot(user) || isAI(user))) + user << "Access denied." + return 1 + + return 0 + +/obj/machinery/turretid/attackby(obj/item/weapon/W, mob/user) + if(stat & BROKEN) + return + + if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) + if(src.allowed(usr)) + if(emagged) + user << "The turret control is unresponsive." + else + locked = !locked + user << "You [ locked ? "lock" : "unlock"] the panel." + return + return ..() + +/obj/machinery/turretid/emag_act(user as mob) + if(!emagged) + user << "You short out the turret controls' access analysis module." + emagged = 1 + locked = 0 + ailock = 0 + return + +/obj/machinery/turretid/attack_ai(mob/user as mob) + if(isLocked(user)) + return + + ui_interact(user) + +/obj/machinery/turretid/attack_hand(mob/user as mob) + if(isLocked(user)) + return + + ui_interact(user) + +/obj/machinery/turretid/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] + data["access"] = !isLocked(user) + data["locked"] = locked + data["enabled"] = enabled + data["is_lethal"] = 1 + data["lethal"] = lethal + + if(data["access"]) + var/settings[0] + settings[++settings.len] = list("category" = "Neutralize All Non-Synthetics", "setting" = "check_synth", "value" = check_synth) + settings[++settings.len] = list("category" = "Check Weapon Authorization", "setting" = "check_weapons", "value" = check_weapons) + settings[++settings.len] = list("category" = "Check Security Records", "setting" = "check_records", "value" = check_records) + settings[++settings.len] = list("category" = "Check Arrest Status", "setting" = "check_arrest", "value" = check_arrest) + settings[++settings.len] = list("category" = "Check Access Authorization", "setting" = "check_access", "value" = check_access) + settings[++settings.len] = list("category" = "Check Misc. Lifeforms", "setting" = "check_anomalies", "value" = check_anomalies) + data["settings"] = settings + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "turret_control.tmpl", "Turret Controls", 500, 300) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + +/obj/machinery/turretid/Topic(href, href_list, var/nowindow = 0) + if(..()) + return 1 + + if(isLocked(usr)) + return 1 + + if(href_list["command"] && href_list["value"]) + var/value = text2num(href_list["value"]) + if(href_list["command"] == "enable") + enabled = value + else if(href_list["command"] == "lethal") + lethal = value + else if(href_list["command"] == "check_synth") + check_synth = value + else if(href_list["command"] == "check_weapons") + check_weapons = value + else if(href_list["command"] == "check_records") + check_records = value + else if(href_list["command"] == "check_arrest") + check_arrest = value + else if(href_list["command"] == "check_access") + check_access = value + else if(href_list["command"] == "check_anomalies") + check_anomalies = value + + updateTurrets() + return 1 + +/obj/machinery/turretid/proc/updateTurrets() + var/datum/turret_checks/TC = new + TC.enabled = enabled + TC.lethal = lethal + TC.check_synth = check_synth + TC.check_access = check_access + TC.check_records = check_records + TC.check_arrest = check_arrest + TC.check_weapons = check_weapons + TC.check_anomalies = check_anomalies + TC.ailock = ailock + + if(istype(control_area)) + for(var/area/sub_area in control_area.related) + for (var/obj/machinery/porta_turret/aTurret in sub_area) + aTurret.setState(TC) + + update_icon() + +/obj/machinery/turretid/power_change() + ..() + updateTurrets() + update_icon() + +/obj/machinery/turretid/update_icon() + ..() + if(stat & NOPOWER) + icon_state = "control_off" + else if (enabled) + if (lethal) + icon_state = "control_kill" + else + icon_state = "control_stun" + else + icon_state = "control_standby" + +/obj/machinery/turretid/emp_act(severity) + if(enabled) + //if the turret is on, the EMP no matter how severe disables the turret for a while + //and scrambles its settings, with a slight chance of having an emag effect + + check_arrest = pick(0, 1) + check_records = pick(0, 1) + check_weapons = pick(0, 1) + check_access = pick(0, 0, 0, 0, 1) // check_access is a pretty big deal, so it's least likely to get turned on + check_anomalies = pick(0, 1) + + enabled=0 + updateTurrets() + + sleep(rand(60,600)) + if(!enabled) + enabled=1 + updateTurrets() + + ..() diff --git a/code/game/machinery/turrets.dm b/code/game/machinery/turrets.dm index 507d0c1dfe7..171586d255a 100644 --- a/code/game/machinery/turrets.dm +++ b/code/game/machinery/turrets.dm @@ -299,7 +299,8 @@ /obj/machinery/turret/attackby(obj/item/weapon/W, mob/user)//I can't believe no one added this before/N ..() - playsound(get_turf(src), 'sound/weapons/smash.ogg', 60, 1) + user.changeNext_move(CLICK_CD_MELEE) + playsound(src.loc, 'sound/weapons/smash.ogg', 60, 1) src.spark_system.start() src.health -= W.force * 0.5 if (src.health <= 0) @@ -330,127 +331,31 @@ spawn(13) qdel(src) -/obj/machinery/turretid - name = "turret deactivation control" - icon = 'icons/obj/device.dmi' - icon_state = "control_stun" - anchored = 1 - density = 0 - var/enabled = 1 - var/lethal = 0 - var/locked = 1 - var/control_area //can be area name, path or nothing. - var/ailock = 0 // AI cannot use this - req_access = list(access_ai_upload) - -/obj/machinery/turretid/New() - ..() - if(!control_area) - var/area/CA = get_area(src) - if(CA.master && CA.master != CA) - control_area = CA.master - else - control_area = CA - else if(istext(control_area)) - for(var/area/A in world) - if(A.name && A.name==control_area) - control_area = A - break - //don't have to check if control_area is path, since get_area_all_atoms can take path. - return - -/obj/machinery/turretid/attackby(obj/item/weapon/W, mob/user) - if(stat & BROKEN) return - if (istype(user, /mob/living/silicon)) - return src.attack_hand(user) - - if (istype(W, /obj/item/weapon/card/emag) && !emagged) - user << "\red You short out the turret controls' access analysis module." - emagged = 1 - locked = 0 - if(user.machine==src) - src.attack_hand(user) - - return - - else if( get_dist(src, user) == 0 ) // trying to unlock the interface - if (src.allowed(usr)) - if(emagged) - user << "The turret control is unresponsive." - return - - locked = !locked - user << "You [ locked ? "lock" : "unlock"] the panel." - if (locked) - if (user.machine==src) - user.unset_machine() - user << browse(null, "window=turretid") - else - if (user.machine==src) - src.attack_hand(user) - else - user << "Access denied." - -/obj/machinery/turretid/attack_ai(mob/user as mob) - if(!ailock) - return attack_hand(user) - else - user << "There seems to be a firewall preventing you from accessing this device." - -/obj/machinery/turretid/attack_hand(mob/user as mob) - if ( get_dist(src, user) > 0 ) - if ( !issilicon(user) ) - user << "You are too far away." - user.unset_machine() - user << browse(null, "window=turretid;size=500x250") - return - - user.set_machine(src) - var/loc = src.loc - if (istype(loc, /turf)) - loc = loc:loc - if (!istype(loc, /area)) - user << text("Turret badly positioned - loc.loc is [].", loc) - return - var/area/area = loc - var/t = "" - - if(src.locked && (!istype(user, /mob/living/silicon))) - t += "
    Swipe ID card to unlock interface
    " - else - if (!istype(user, /mob/living/silicon)) - t += "
    Swipe ID card to lock interface
    " - t += text("Turrets [] - []?
    \n", src.enabled?"activated":"deactivated", src, src.enabled?"Disable":"Enable") - t += text("Currently set for [] - Change to []?
    \n", src.lethal?"lethal":"stun repeatedly", src, src.lethal?"Stun repeatedly":"Lethal") - - //user << browse(t, "window=turretid;size=500x250") - //onclose(user, "turretid") - var/datum/browser/popup = new(user, "turretid", "Turret Control Panel ([area.name])", 500, 250) - popup.set_content(t) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() - - + /obj/machinery/turret/attack_animal(mob/living/simple_animal/M as mob) + M.changeNext_move(CLICK_CD_MELEE) + M.do_attack_animation(src) if(M.melee_damage_upper == 0) return if(!(stat & BROKEN)) - visible_message("\red [M] [M.attacktext] [src]!") - M.attack_log += text("\[[time_stamp()]\] attacked [src.name]") + visible_message("[M] [M.attacktext] [src]!") + add_logs(M, src, "attacked", admin=0) //src.attack_log += text("\[[time_stamp()]\] was attacked by [M.name] ([M.ckey])") src.health -= M.melee_damage_upper if (src.health <= 0) src.die() else - M << "\red That object is useless to you." + M << "That object is useless to you." return /obj/machinery/turret/attack_alien(mob/living/carbon/alien/humanoid/M as mob) + M.changeNext_move(CLICK_CD_MELEE) + M.do_attack_animation(src) if(!(stat & BROKEN)) - playsound(get_turf(src), 'sound/weapons/slash.ogg', 25, 1, -1) - visible_message("\red [] has slashed at []!", M, src) + playsound(src.loc, 'sound/weapons/slash.ogg', 25, 1, -1) + visible_message("[M] has slashed at [src]!") src.health -= 15 if (src.health <= 0) src.die() @@ -460,9 +365,9 @@ -/obj/machinery/turretid/Topic(href, href_list) - if(..()) - return +/obj/machinery/turretid/Topic(href, href_list, var/nowindow = 0) + if(..(href, href_list)) + return 1 if (src.locked) if (!istype(usr, /mob/living/silicon)) usr << "Control panel is locked!" @@ -473,13 +378,8 @@ else if (href_list["toggleLethal"]) src.lethal = !src.lethal src.updateTurrets() - src.attack_hand(usr) - -/obj/machinery/turretid/proc/updateTurrets() - if(control_area) - for (var/obj/machinery/turret/aTurret in get_area_all_atoms(control_area)) - aTurret.setState(enabled, lethal) - src.update_icons() + if(!nowindow) + src.attack_hand(usr) /obj/machinery/turretid/proc/update_icons() if (src.enabled) @@ -558,8 +458,9 @@ /obj/machinery/gun_turret/bullet_act(var/obj/item/projectile/Proj) - take_damage(Proj.damage) - return + if((Proj.damage_type == BRUTE || Proj.damage_type == BURN)) + take_damage(Proj.damage) + return /obj/machinery/gun_turret/proc/die() state = 2 @@ -572,7 +473,10 @@ return attack_hand(user) -/obj/machinery/gun_turret/attack_alien(mob/user as mob) +/obj/machinery/gun_turret/attack_alien(mob/living/user as mob) + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) + playsound(src.loc, 'sound/weapons/slash.ogg', 25, 1, -1) user.visible_message("[user] slashes at [src]", "You slash at [src]") take_damage(15) return diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 348456523eb..c8987cccad0 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -1,17 +1,39 @@ -#define CAT_NORMAL 0 -#define CAT_HIDDEN 1 -#define CAT_COIN 2 +#define CAT_NORMAL 1 +#define CAT_HIDDEN 2 // also used in corresponding wires/vending.dm +#define CAT_COIN 4 +/** + * Datum used to hold information about a product in a vending machine + */ /datum/data/vending_product - var/product_name = "generic" + var/product_name = "generic" // Display name for the product var/product_path = null - var/amount = 0 + var/amount = 0 // Amount held in the vending machine var/max_amount = 0 - var/price = 0 - var/display_color = "blue" - var/category = CAT_NORMAL + var/price = 0 // Price to buy one + var/display_color = null // Display color for vending machine listing + var/category = CAT_NORMAL // CAT_HIDDEN for contraband, CAT_COIN for premium +/datum/data/vending_product/New(var/path, var/name = null, var/amount = 1, var/price = 0, var/color = null, var/category = CAT_NORMAL) + ..() + src.product_path = path + + if(!name) + var/atom/tmp = new path + src.product_name = initial(tmp.name) + del(tmp) + else + src.product_name = name + + src.amount = amount + src.price = price + src.display_color = color + src.category = category + +/** + * A vending machine + */ /obj/machinery/vending name = "Vendomat" desc = "A generic vending machine." @@ -20,11 +42,23 @@ layer = 2.9 anchored = 1 density = 1 + + var/icon_vend //Icon_state when vending + var/icon_deny //Icon_state when denying access + + // Power + use_power = 1 + idle_power_usage = 10 + var/vend_power_usage = 150 + + // Vending-related var/active = 1 //No sales pitches if off! - var/delay_product_spawn // If set, uses sleep() in product spawn proc (mostly for seeds to retrieve correct names). var/vend_ready = 1 //Are we ready to vend?? Is it time?? var/vend_delay = 10 //How long does it take to vend? - var/datum/data/vending_product/currently_vending = null // A /datum/data/vending_product instance of what we're paying for right now. + var/categories = CAT_NORMAL // Bitmask of cats we're currently showing + var/datum/data/vending_product/currently_vending = null // What we're requesting payment for right now + var/status_message = "" // Status screen messages like "insufficient funds", displayed in NanoUI + var/status_error = 0 // Set to 1 if status_message is an error // To be filled out at compile time var/list/products = list() // For each, use the following pattern: @@ -32,27 +66,33 @@ var/list/premium = list() // No specified amount = only one in stock var/list/prices = list() // Prices for each item, list(/type/path = price), items not in the list don't have a price. - var/product_slogans = "" //String of slogans separated by semicolons, optional - var/product_ads = "" //String of small ad messages in the vending screen - random chance + // List of vending_product items available. var/list/product_records = list() var/list/hidden_records = list() - var/list/coin_records = list() + + // // Variables used to initialize advertising + var/product_slogans = "" //String of slogans separated by semicolons, optional + var/product_ads = "" //String of small ad messages in the vending screen - random chance + + var/list/ads_list = list() + + // Stuff relating vocalizations var/list/slogan_list = list() - var/list/small_ads = list() //Small ad messages in the vending screen - random chance of popping up whenever you open it var/vend_reply //Thank you for shopping! + var/shut_up = 0 //Stop spouting those godawful pitches! var/last_reply = 0 - var/obj/item/weapon/vending_refill/refill_canister = null //The type of refill canisters used by this machine. var/last_slogan = 0 //When did we last pitch? var/slogan_delay = 6000 //How long until we can pitch again? - var/icon_vend //Icon_state when vending! - var/icon_deny //Icon_state when vending! - //var/emagged = 0 //Ignores if somebody doesn't have card access to that machine. + + var/obj/item/weapon/vending_refill/refill_canister = null //The type of refill canisters used by this machine. + + // Things that can go wrong + emagged = 0 //Ignores if somebody doesn't have card access to that machine. var/seconds_electrified = 0 //Shock customers like an airlock. var/shoot_inventory = 0 //Fire items at customers! We're broken! var/shoot_speed = 3 //How hard are we firing the items? var/shoot_chance = 2 //How often are we firing the items? - var/shut_up = 0 //Stop spouting those godawful pitches! - var/extended_inventory = 0 //can we access the hidden inventory? + var/scan_id = 1 var/obj/item/weapon/coin/coin var/datum/wires/vending/wires = null @@ -60,32 +100,57 @@ /obj/machinery/vending/New() ..() wires = new(src) - spawn(4) - src.slogan_list = text2list(src.product_slogans, ";") + spawn(50) + if(src.product_slogans) + src.slogan_list += text2list(src.product_slogans, ";") - // So not all machines speak at the exact same time. - // The first time this machine says something will be at slogantime + this random value, - // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated. - src.last_slogan = world.time + rand(0, slogan_delay) + // So not all machines speak at the exact same time. + // The first time this machine says something will be at slogantime + this random value, + // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated. + src.last_slogan = world.time + rand(0, slogan_delay) - src.build_inventory(products) - //Add hidden inventory - src.build_inventory(contraband, 1) - src.build_inventory(premium, 0, 1) + if(src.product_ads) + src.ads_list += text2list(src.product_ads, ";") + + src.build_inventory() power_change() - - return return +/** + * Build src.produdct_records from the products lists + * + * src.products, src.contraband, src.premium, and src.prices allow specifying + * products that the vending machine is to carry without manually populating + * src.product_records. + */ +/obj/machinery/vending/proc/build_inventory() + var/list/all_products = list( + list(src.products, CAT_NORMAL), + list(src.contraband, CAT_HIDDEN), + list(src.premium, CAT_COIN)) + + for(var/current_list in all_products) + var/category = current_list[2] + + for(var/entry in current_list[1]) + var/datum/data/vending_product/product = new/datum/data/vending_product(entry) + + product.price = (entry in src.prices) ? src.prices[entry] : 0 + product.amount = (current_list[1][entry]) ? current_list[1][entry] : 1 + product.max_amount = product.amount + product.category = category + + src.product_records.Add(product) /obj/machinery/vending/Destroy() - del(wires) + del(wires) // qdel wires = null - del(coin) - coin = null + if(coin) + del(coin) // qdel + coin = null ..() /obj/machinery/vending/ex_act(severity) @@ -115,41 +180,6 @@ else del(src) - -/obj/machinery/vending/proc/build_inventory(var/list/productlist,hidden=0,req_coin=0,start_empty = null) - for(var/typepath in productlist) - var/amount = productlist[typepath] - var/price = prices[typepath] - if(isnull(amount)) amount = 1 - - var/atom/temp = new typepath(null) - var/datum/data/vending_product/R = new /datum/data/vending_product() - - R.product_path = typepath - if(!start_empty) - R.amount = amount - R.max_amount = amount - R.price = price - R.display_color = pick("red","blue","green") - if(hidden) - R.category=CAT_HIDDEN - hidden_records += R - else if(req_coin) - R.category=CAT_COIN - coin_records += R - else - R.category=CAT_NORMAL - product_records += R - - if(delay_product_spawn) - sleep(3) - R.product_name = temp.name - else - R.product_name = temp.name - -// world << "Added: [R.product_name]] - [R.amount] - [R.product_path]" - - /obj/machinery/vending/proc/refill_inventory(obj/item/weapon/vending_refill/refill, datum/data/vending_product/machine, mob/user) var/total = 0 @@ -179,11 +209,42 @@ break return total -/obj/machinery/vending/attackby(obj/item/weapon/W, mob/user) - if(panel_open) - if(default_unfasten_wrench(user, W, time = 60)) - return +/obj/machinery/vending/attackby(obj/item/weapon/W, mob/user, params) + if (currently_vending && vendor_account && !vendor_account.suspended) + var/paid = 0 + var/handled = 0 + if(istype(W, /obj/item/weapon/card/id)) + var/obj/item/weapon/card/id/C = W + paid = pay_with_card(C) + handled = 1 + else if (istype(W, /obj/item/weapon/spacecash)) + var/obj/item/weapon/spacecash/C = W + paid = pay_with_cash(C, user) + handled = 1 + if(paid) + src.vend(currently_vending, usr) + return + else if(handled) + nanomanager.update_uis(src) + return // don't smack that machine with your 2 thalers + + if(default_unfasten_wrench(user, W, time = 60)) + return + + if(istype(W, /obj/item/weapon/screwdriver) && anchored) + playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) + panel_open = !panel_open + user << "You [panel_open ? "open" : "close"] the maintenance panel." + overlays.Cut() + if(panel_open) + overlays += image(icon, "[initial(icon_state)]-panel") + nanomanager.update_uis(src) // Speaker switch is on the main UI, not wires UI + return + + if(panel_open) + if(istype(W, /obj/item/device/multitool)||istype(W, /obj/item/weapon/wirecutters)) + return attack_hand(user) if(component_parts && istype(W, /obj/item/weapon/crowbar)) var/datum/data/vending_product/machine = product_records for(var/datum/data/vending_product/machine_content in machine) @@ -194,32 +255,13 @@ if(!machine_content.amount) break default_deconstruction_crowbar(W) - - if(istype(W, /obj/item/weapon/card/emag)) - emagged = 1 - user << "You short out the product lock on [src]" - return - else if(istype(W, /obj/item/weapon/screwdriver) && anchored) - playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) - panel_open = !panel_open - user << "You [panel_open ? "open" : "close"] the maintenance panel." - overlays.Cut() - if(panel_open) - overlays += image(icon, "[initial(icon_state)]-panel") - updateUsrDialog() - return - else if(istype(W, /obj/item/device/multitool)||istype(W, /obj/item/weapon/wirecutters)) - if(panel_open) - attack_hand(user) - return - 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/coin) && premium.len > 0) + if(istype(W, /obj/item/weapon/coin) && premium.len > 0) user.drop_item() W.loc = src coin = W - user << "You insert [W] into [src]." + categories |= CAT_COIN + user << "\blue You insert the [W] into the [src]" + nanomanager.update_uis(src) return else if(istype(W, refill_canister) && refill_canister != null) if(stat & (BROKEN|NOPOWER)) @@ -241,175 +283,188 @@ else ..() +/obj/machinery/vending/emag_act(user as mob) + emagged = 1 + user << "You short out the product lock on [src]" + return +/** + * Receive payment with cashmoney. + * + * usr is the mob who gets the change. + */ +/obj/machinery/vending/proc/pay_with_cash(var/obj/item/weapon/spacecash/cashmoney, mob/user) + if(currently_vending.price > cashmoney.worth) + // This is not a status display message, since it's something the character + // themselves is meant to see BEFORE putting the money in + usr << "\icon[cashmoney] That is not enough money." + return 0 -/obj/machinery/vending/proc/scan_card(var/obj/item/weapon/card/I) - if(!currently_vending) return - if (istype(I, /obj/item/weapon/card/id)) - var/obj/item/weapon/card/id/C = I - visible_message("[usr] swipes a card through [src].") - if(vendor_account) - var/datum/money_account/D = attempt_account_access_nosec(C.associated_account_number) - if(D) - var/transaction_amount = currently_vending.price - if(transaction_amount <= D.money) + // Bills (banknotes) cannot really have worth different than face value, + // so we have to eat the bill and spit out change in a bundle + // This is really dirty, but there's no superclass for all bills, so we + // just assume that all spacecash that's not something else is a bill - //transfer the money - D.money -= transaction_amount - vendor_account.money += transaction_amount + visible_message("[usr] inserts a credit chip into [src].") + var/left = cashmoney.worth - currently_vending.price + usr.unEquip(cashmoney) + del(cashmoney) - //create entries in the two account transaction logs - var/datum/transaction/T = new() - T.target_name = "[vendor_account.owner_name] (via [src.name])" - T.purpose = "Purchase of [currently_vending.product_name]" - if(transaction_amount > 0) - T.amount = "([transaction_amount])" - else - T.amount = "[transaction_amount]" - T.source_terminal = src.name - T.date = current_date_string - T.time = worldtime2text() - D.transaction_log.Add(T) - // - T = new() - T.target_name = D.owner_name - T.purpose = "Purchase of [currently_vending.product_name]" - T.amount = "[transaction_amount]" - T.source_terminal = src.name - T.date = current_date_string - T.time = worldtime2text() - vendor_account.transaction_log.Add(T) + if(left) + dispense_cash(left, src.loc, user) - // Vend the item - src.vend(src.currently_vending, usr) - currently_vending = null - src.updateUsrDialog() - else - usr << "\icon[src]You don't have that much money!" - else - usr << "\icon[src]Unable to access account. Check security settings and try again." + // Vending machines have no idea who paid with cash + credit_purchase("(cash)") + return 1 + +/** + * Scan a card and attempt to transfer payment from associated account. + * + * Takes payment for whatever is the currently_vending item. Returns 1 if + * successful, 0 if failed + */ +/obj/machinery/vending/proc/pay_with_card(var/obj/item/weapon/card/id/I) + visible_message("[usr] swipes a card through [src].") + var/datum/money_account/customer_account = attempt_account_access_nosec(I.associated_account_number) + if (!customer_account) + src.status_message = "Error: Unable to access account. Please contact technical support if problem persists." + src.status_error = 1 + return 0 + + if(customer_account.suspended) + src.status_message = "Unable to access account: account suspended." + src.status_error = 1 + return 0 + + // Have the customer punch in the PIN before checking if there's enough money. Prevents people from figuring out acct is + // empty at high security levels + if(customer_account.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2) + var/attempt_pin = input("Enter pin code", "Vendor transaction") as num + customer_account = attempt_account_access(I.associated_account_number, attempt_pin, 2) + + if(!customer_account) + src.status_message = "Unable to access account: incorrect credentials." + src.status_error = 1 + return 0 + + if(currently_vending.price > customer_account.money) + src.status_message = "Insufficient funds in account." + src.status_error = 1 + return 0 + else + // Okay to move the money at this point + + // debit money from the purchaser's account + customer_account.money -= currently_vending.price + + // create entry in the purchaser's account log + var/datum/transaction/T = new() + T.target_name = "[vendor_account.owner_name] (via [src.name])" + T.purpose = "Purchase of [currently_vending.product_name]" + if(currently_vending.price > 0) + T.amount = "([currently_vending.price])" else - usr << "\icon[src]Unable to access vendor account. Please record the machine ID and call CentComm Support." + T.amount = "[currently_vending.price]" + T.source_terminal = src.name + T.date = current_date_string + T.time = worldtime2text() + customer_account.transaction_log.Add(T) -/obj/machinery/vending/attack_paw(mob/user as mob) - return attack_hand(user) + // Give the vendor the money. We use the account owner name, which means + // that purchases made with stolen/borrowed card will look like the card + // owner made them + credit_purchase(customer_account.owner_name) + return 1 + +/** + * Add money for current purchase to the vendor account. + * + * Called after the money has already been taken from the customer. + */ +/obj/machinery/vending/proc/credit_purchase(var/target as text) + vendor_account.money += currently_vending.price + + var/datum/transaction/T = new() + T.target_name = target + T.purpose = "Purchase of [currently_vending.product_name]" + T.amount = "[currently_vending.price]" + T.source_terminal = src.name + T.date = current_date_string + T.time = worldtime2text() + vendor_account.transaction_log.Add(T) /obj/machinery/vending/attack_ai(mob/user as mob) return attack_hand(user) -/obj/machinery/vending/proc/GetProductIndex(var/datum/data/vending_product/P) - var/list/plist - switch(P.category) - if(CAT_NORMAL) - plist=product_records - if(CAT_HIDDEN) - plist=hidden_records - if(CAT_COIN) - plist=coin_records - else - warning("UNKNOWN CATEGORY [P.category] IN TYPE [P.product_path] INSIDE [type]!") - return plist.Find(P) - -/obj/machinery/vending/proc/GetProductByID(var/pid, var/category) - switch(category) - if(CAT_NORMAL) - return product_records[pid] - if(CAT_HIDDEN) - return hidden_records[pid] - if(CAT_COIN) - return coin_records[pid] - else - warning("UNKNOWN PRODUCT: PID: [pid], CAT: [category] INSIDE [type]!") - return null +/obj/machinery/vending/attack_paw(mob/user as mob) + return attack_hand(user) /obj/machinery/vending/attack_hand(mob/user as mob) if(stat & (BROKEN|NOPOWER)) return - user.set_machine(src) - if(seconds_electrified != 0) - if(shock(user, 100)) + if(src.seconds_electrified != 0) + if(src.shock(user, 100)) return - var/vendorname = (src.name) //import the machine's name + ui_interact(user) + wires.Interact(user) - if(src.currently_vending) - var/dat = "
    [vendorname]


    " //display the name, and added a horizontal rule +/** + * Display the NanoUI window for the vending machine. + * + * See NanoUI documentation for details. + */ +/obj/machinery/vending/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) - // AUTOFIXED BY fix_string_idiocy.py - // C:\Users\Rob\Documents\Projects\vgstation13\code\game\machinery\vending.dm:260: dat += "You have selected [currently_vending.product_name].
    Please ensure your ID is in your ID holder or hand.

    " - dat += {"You have selected [currently_vending.product_name].
    Please ensure your ID is in your ID holder or hand.

    - Pay | - Cancel"} - // END AUTOFIX - user << browse(dat, "window=vending") - onclose(user, "") - return - - var/dat = "
    [vendorname]


    " //display the name, and added a horizontal rule - 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)

    " - - if (src.product_records.len == 0) - dat += "No product loaded!" + var/list/data = list() + if(currently_vending) + data["mode"] = 1 + data["product"] = currently_vending.product_name + data["price"] = currently_vending.price + data["message_err"] = 0 + data["message"] = src.status_message + data["message_err"] = src.status_error else - var/list/display_records = list() - display_records += src.product_records + data["mode"] = 0 + var/list/listed_products = list() - if(src.extended_inventory) - display_records += src.hidden_records - if(src.coin) - display_records += src.coin_records + for(var/key = 1 to src.product_records.len) + var/datum/data/vending_product/I = src.product_records[key] - for (var/datum/data/vending_product/R in display_records) + if(!(I.category & src.categories)) + continue - // AUTOFIXED BY fix_string_idiocy.py - // C:\Users\Rob\Documents\Projects\vgstation13\code\game\machinery\vending.dm:285: dat += "[R.product_name]:" - dat += {"[R.product_name]: - [R.amount] "} - // END AUTOFIX - if(R.price) - dat += " (Price: [R.price])" - if (R.amount > 0) - var/idx=GetProductIndex(R) - dat += " (Vend)" - else - dat += " SOLD OUT" - dat += "
    " + listed_products.Add(list(list( + "key" = key, + "name" = sanitize(I.product_name), + "price" = I.price, + "color" = I.display_color, + "amount" = I.amount))) - dat += "
    " + data["products"] = listed_products - if(panel_open) - dat += wires() + if(src.coin) + data["coin"] = src.coin.name - if(product_slogans != "") - dat += "The speaker switch is [shut_up ? "off" : "on"]. Toggle" + if(src.panel_open) + data["panel"] = 1 + data["speaker"] = src.shut_up ? 0 : 1 + else + data["panel"] = 0 - user << browse(dat, "window=vending") - onclose(user, "") - return - -// returns the wire panel text -/obj/machinery/vending/proc/wires() - return wires.GetInteractWindow() + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "vending_machine.tmpl", src.name, 440, 600) + ui.set_initial_data(data) + ui.open() /obj/machinery/vending/Topic(href, href_list) if(..()) - return + return 1 - if(istype(usr,/mob/living/silicon)) - if(istype(usr,/mob/living/silicon/robot)) - var/mob/living/silicon/robot/R = usr - if(!(R.module && istype(R.module,/obj/item/weapon/robot_module/butler) ) ) - usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!" - return - else - usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!" - return - - if(href_list["remove_coin"]) + if(href_list["remove_coin"] && !istype(usr,/mob/living/silicon)) if(!coin) usr << "There is no coin in this machine." return @@ -419,67 +474,86 @@ usr.put_in_hands(coin) usr << "\blue You remove the [coin] from the [src]" coin = null - usr.set_machine(src) + categories &= ~CAT_COIN + if (href_list["pay"]) + if(currently_vending && vendor_account && !vendor_account.suspended) + if(istype(usr, /mob/living/carbon/human)) + var/paid = 0 + var/handled = 0 + var/mob/living/carbon/human/H = usr + var/obj/item/weapon/card/card = null + if(istype(H.wear_id,/obj/item/weapon/card)) + card = H.wear_id + paid = pay_with_card(card) + handled = 1 + else if(istype(H.get_active_hand(), /obj/item/weapon/card)) + card = H.get_active_hand() + paid = pay_with_card(card) + handled = 1 + if(paid) + src.vend(currently_vending, usr) + return + else if(handled) + nanomanager.update_uis(src) + return // don't smack that machine with your 2 credits if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf)))) if ((href_list["vend"]) && (src.vend_ready) && (!currently_vending)) - if (!allowed(usr) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH - usr << "\red Access denied." //Unless emagged of course - flick(src.icon_deny,src) + if(istype(usr,/mob/living/silicon)) + if(istype(usr,/mob/living/silicon/robot)) + var/mob/living/silicon/robot/R = usr + if(!(R.module && istype(R.module,/obj/item/weapon/robot_module/butler) )) + usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!" + return + else + usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!" + return + + if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH + usr << "Access denied." //Unless emagged of course + flick(icon_deny,src) return - var/idx=text2num(href_list["vend"]) - var/cat=text2num(href_list["cat"]) + var/key = text2num(href_list["vend"]) + var/datum/data/vending_product/R = product_records[key] - var/datum/data/vending_product/R = GetProductByID(idx,cat) - if (!R || !istype(R) || !R.product_path || R.amount <= 0) + // This should not happen unless the request from NanoUI was bad + if(!(R.category & src.categories)) return - if(R.price == null) + if(R.price <= 0) src.vend(R, usr) else src.currently_vending = R - src.updateUsrDialog() + if(!vendor_account || vendor_account.suspended) + src.status_message = "This machine is currently unable to process payments due to problems with the associated account." + src.status_error = 1 + else + src.status_message = "Please swipe a card or insert cash to pay for the item." + src.status_error = 0 - return - - else if (href_list["cancel_buying"]) + else if (href_list["cancelpurchase"]) src.currently_vending = null - src.updateUsrDialog() - return - - else if (href_list["buy"]) - if(istype(usr, /mob/living/carbon/human)) - var/mob/living/carbon/human/H=usr - var/obj/item/weapon/card/card = null - if(istype(H.wear_id,/obj/item/weapon/card)) - card=H.wear_id - else if(istype(H.get_active_hand(),/obj/item/weapon/card)) - card=H.get_active_hand() - if(card) - scan_card(card) - return else if ((href_list["togglevoice"]) && (src.panel_open)) src.shut_up = !src.shut_up src.add_fingerprint(usr) - src.updateUsrDialog() - else - usr << browse(null, "window=vending") - return - return + nanomanager.update_uis(src) /obj/machinery/vending/proc/vend(datum/data/vending_product/R, mob/user) - if (!allowed(user) && !emagged && wires.IsIndexCut(VENDING_WIRE_IDSCAN)) //For SECURE VENDING MACHINES YEAH - user << "\red Access denied." //Unless emagged of course + if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH + usr << "Access denied." //Unless emagged of course flick(src.icon_deny,src) return src.vend_ready = 0 //One thing at a time!! + src.status_message = "Vending..." + src.status_error = 0 + nanomanager.update_uis(src) - if (R in coin_records) + if (R.category & CAT_COIN) if(!coin) user << "\blue You need to insert a coin to get this item." return @@ -489,8 +563,10 @@ else user << "\blue You weren't able to pull the coin out fast enough, the machine ate it, string and all." del(coin) + categories &= ~CAT_COIN else del(coin) + categories &= ~CAT_COIN R.amount-- @@ -499,16 +575,16 @@ src.speak(src.vend_reply) src.last_reply = world.time - use_power(5) + use_power(vend_power_usage) //actuators and stuff if (src.icon_vend) //Show the vending animation if needed flick(src.icon_vend,src) spawn(src.vend_delay) new R.product_path(get_turf(src)) + src.status_message = "" + src.status_error = 0 src.vend_ready = 1 - return - - src.updateUsrDialog() - + currently_vending = null + nanomanager.update_uis(src) /obj/machinery/vending/proc/stock(var/datum/data/vending_product/R, var/mob/user) if(src.panel_open) @@ -771,9 +847,13 @@ product_slogans = "Carts to go!" 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/captain = 3,/obj/item/weapon/cartridge/quartermaster = 10) + products = list(/obj/item/device/pda =10,/obj/item/weapon/cartridge/medical = 10,/obj/item/weapon/cartridge/chemistry = 10, + /obj/item/weapon/cartridge/engineering = 10,/obj/item/weapon/cartridge/atmos = 10,/obj/item/weapon/cartridge/janitor = 10, + /obj/item/weapon/cartridge/signal/toxins = 10,/obj/item/weapon/cartridge/signal = 10,/obj/item/weapon/cartridge = 10) + contraband = list(/obj/item/weapon/cartridge/clown = 1,/obj/item/weapon/cartridge/mime = 1) + prices = list(/obj/item/device/pda =300,/obj/item/weapon/cartridge/medical = 200,/obj/item/weapon/cartridge/chemistry = 150,/obj/item/weapon/cartridge/engineering = 100, + /obj/item/weapon/cartridge/atmos = 75,/obj/item/weapon/cartridge/janitor = 100,/obj/item/weapon/cartridge/signal/toxins = 150, + /obj/item/weapon/cartridge/signal = 75,/obj/item/weapon/cartridge = 50) /obj/machinery/vending/cigarette name = "Cigarette machine" //OCD had to be uppercase to look nice with the new formating @@ -809,7 +889,7 @@ /obj/item/weapon/reagent_containers/glass/bottle/stoxin = 4,/obj/item/weapon/reagent_containers/glass/bottle/toxin = 4, /obj/item/weapon/reagent_containers/syringe/antiviral = 4,/obj/item/weapon/reagent_containers/syringe = 12, /obj/item/device/healthanalyzer = 5,/obj/item/weapon/reagent_containers/glass/beaker = 4, /obj/item/weapon/reagent_containers/dropper = 2, - /obj/item/stack/medical/advanced/bruise_pack = 3, /obj/item/stack/medical/advanced/ointment = 3, /obj/item/stack/medical/splint = 2) + /obj/item/stack/medical/advanced/bruise_pack = 3, /obj/item/stack/medical/advanced/ointment = 3, /obj/item/stack/medical/splint = 2, /obj/item/device/sensor_device = 2) contraband = list(/obj/item/weapon/reagent_containers/pill/tox = 3,/obj/item/weapon/reagent_containers/pill/stox = 4,/obj/item/weapon/reagent_containers/pill/antitox = 6) @@ -860,7 +940,7 @@ icon_state = "sec" icon_deny = "sec-deny" req_access_txt = "1" - products = list(/obj/item/weapon/handcuffs = 8,/obj/item/weapon/grenade/flashbang = 4,/obj/item/device/flash = 5, + products = list(/obj/item/weapon/restraints/handcuffs = 8,/obj/item/weapon/restraints/handcuffs/cable/zipties = 8,/obj/item/weapon/grenade/flashbang = 4,/obj/item/device/flash = 5, /obj/item/weapon/reagent_containers/food/snacks/donut/normal = 12,/obj/item/weapon/storage/box/evidence = 6,/obj/item/device/flashlight/seclite = 4) contraband = list(/obj/item/clothing/glasses/sunglasses = 2,/obj/item/weapon/storage/fancy/donut_box = 2,/obj/item/device/hailer = 5) @@ -883,19 +963,45 @@ product_slogans = "THIS'S WHERE TH' SEEDS LIVE! GIT YOU SOME!;Hands down the best seed selection on the station!;Also certain mushroom varieties available, more for experts! Get certified today!" product_ads = "We like plants!;Grow some crops!;Grow, baby, growww!;Aw h'yeah son!" icon_state = "seeds" - delay_product_spawn = 1 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/lemonseed = 3,/obj/item/seeds/orangeseed = 3,/obj/item/seeds/grassseed = 3,/obj/item/seeds/cocoapodseed = 3, - /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) + /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, + /obj/item/seeds/tobaccoseed = 3, /obj/item/seeds/coffeeaseed = 3, /obj/item/seeds/teaasperaseed = 3) contraband = list(/obj/item/seeds/amanitamycelium = 2,/obj/item/seeds/glowshroom = 2,/obj/item/seeds/libertymycelium = 2,/obj/item/seeds/nettleseed = 2, /obj/item/seeds/plumpmycelium = 2,/obj/item/seeds/reishimycelium = 2) premium = list(/obj/item/weapon/reagent_containers/spray/waterflower = 1) +/** + * Populate hydroseeds product_records + * + * This needs to be customized to fetch the actual names of the seeds, otherwise + * the machine would simply list "packet of seeds" times 20 + */ +/obj/machinery/vending/hydroseeds/build_inventory() + var/list/all_products = list( + list(src.products, CAT_NORMAL), + list(src.contraband, CAT_HIDDEN), + list(src.premium, CAT_COIN)) + + for(var/current_list in all_products) + var/category = current_list[2] + + for(var/entry in current_list[1]) + var/obj/item/seeds/S = new entry(src) + var/name = S.name + var/datum/data/vending_product/product = new/datum/data/vending_product(entry, name) + + product.price = (entry in src.prices) ? src.prices[entry] : 0 + product.amount = (current_list[1][entry]) ? current_list[1][entry] : 1 + product.max_amount = product.amount + product.category = category + + src.product_records.Add(product) /obj/machinery/vending/magivend name = "MagiVend" @@ -919,10 +1025,10 @@ /obj/item/clothing/head/helmet/gladiator = 1,/obj/item/clothing/under/gimmick/rank/captain/suit = 1,/obj/item/clothing/head/flatcap = 1, /obj/item/clothing/suit/storage/labcoat/mad = 1,/obj/item/clothing/glasses/gglasses = 1,/obj/item/clothing/shoes/jackboots = 1, /obj/item/clothing/under/schoolgirl = 1,/obj/item/clothing/head/kitty = 1,/obj/item/clothing/under/blackskirt = 1,/obj/item/clothing/head/beret = 1, - /obj/item/clothing/tie/waistcoat = 1,/obj/item/clothing/under/suit_jacket = 1,/obj/item/clothing/head/that =1,/obj/item/clothing/under/kilt = 1,/obj/item/clothing/head/beret = 1,/obj/item/clothing/tie/waistcoat = 1, + /obj/item/clothing/accessory/waistcoat = 1,/obj/item/clothing/under/suit_jacket = 1,/obj/item/clothing/head/that =1,/obj/item/clothing/under/kilt = 1,/obj/item/clothing/head/beret = 1,/obj/item/clothing/accessory/waistcoat = 1, /obj/item/clothing/glasses/monocle =1,/obj/item/clothing/head/bowlerhat = 1,/obj/item/weapon/cane = 1,/obj/item/clothing/under/sl_suit = 1, /obj/item/clothing/mask/fakemoustache = 1,/obj/item/clothing/suit/bio_suit/plaguedoctorsuit = 1,/obj/item/clothing/head/plaguedoctorhat = 1,/obj/item/clothing/mask/gas/plaguedoctor = 1, - /obj/item/clothing/under/owl = 1,/obj/item/clothing/mask/gas/owl_mask = 1,/obj/item/clothing/suit/apron = 1,/obj/item/clothing/under/waiter = 1, + /obj/item/clothing/suit/apron = 1,/obj/item/clothing/under/waiter = 1, /obj/item/clothing/under/pirate = 1,/obj/item/clothing/suit/pirate_brown = 1,/obj/item/clothing/suit/pirate_black =1,/obj/item/clothing/under/pirate_rags =1,/obj/item/clothing/head/pirate = 1,/obj/item/clothing/head/bandana = 1, /obj/item/clothing/head/bandana = 1,/obj/item/clothing/under/soviet = 1,/obj/item/clothing/head/ushanka = 1,/obj/item/clothing/suit/imperium_monk = 1, /obj/item/clothing/mask/gas/cyborg = 1,/obj/item/clothing/suit/holidaypriest = 1,/obj/item/clothing/head/wizard/marisa/fake = 1, @@ -930,9 +1036,9 @@ /obj/item/clothing/suit/wizrobe/fake = 1,/obj/item/clothing/head/wizard/fake = 1,/obj/item/weapon/staff = 3,/obj/item/clothing/mask/gas/sexyclown = 1, /obj/item/clothing/under/sexyclown = 1,/obj/item/clothing/mask/gas/sexymime = 1,/obj/item/clothing/under/sexymime = 1,/obj/item/clothing/suit/apron/overalls = 1, /obj/item/clothing/head/rabbitears =1, /obj/item/clothing/head/sombrero = 1, /obj/item/clothing/suit/poncho = 1, - /obj/item/clothing/suit/poncho/green = 1, /obj/item/clothing/suit/poncho/red = 1, /obj/item/clothing/tie/blue = 1, /obj/item/clothing/tie/red = 1, /obj/item/clothing/tie/black = 1, /obj/item/clothing/tie/horrible = 1, - /obj/item/clothing/under/maid = 1, /obj/item/clothing/under/janimaid = 1) - contraband = list(/obj/item/clothing/suit/judgerobe = 1,/obj/item/clothing/head/powdered_wig = 1,/obj/item/weapon/gun/magic/wand = 1) + /obj/item/clothing/suit/poncho/green = 1, /obj/item/clothing/suit/poncho/red = 1, /obj/item/clothing/accessory/blue = 1, /obj/item/clothing/accessory/red = 1, /obj/item/clothing/accessory/black = 1, /obj/item/clothing/accessory/horrible = 1, + /obj/item/clothing/under/maid = 1, /obj/item/clothing/under/janimaid = 1, /obj/item/clothing/under/pants/camo = 1, /obj/item/clothing/mask/bandana = 1, /obj/item/clothing/mask/bandana/black = 1) + contraband = list(/obj/item/clothing/suit/judgerobe = 1,/obj/item/clothing/head/powdered_wig = 1,/obj/item/weapon/gun/magic/wand = 1, /obj/item/clothing/mask/balaclava=1) premium = list(/obj/item/clothing/suit/hgpirate = 1, /obj/item/clothing/head/hgpiratecap = 1, /obj/item/clothing/head/helmet/roman = 1, /obj/item/clothing/head/helmet/roman/legionaire = 1, /obj/item/clothing/under/roman = 1, /obj/item/clothing/shoes/roman = 1) refill_canister = /obj/item/weapon/vending_refill/autodrobe @@ -951,7 +1057,7 @@ desc = "A kitchen and restaurant equipment vendor" product_ads = "Mm, food stuffs!;Food and food accessories.;Get your plates!;You like forks?;I like forks.;Woo, utensils.;You don't really need these..." icon_state = "dinnerware" - products = list(/obj/item/weapon/tray = 8,/obj/item/weapon/kitchen/utensil/fork = 6,/obj/item/weapon/kitchenknife = 3,/obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 8,/obj/item/clothing/suit/chef/classic = 2,/obj/item/weapon/reagent_containers/food/condiment/pack/ketchup = 5,/obj/item/weapon/reagent_containers/food/condiment/pack/hotsauce = 5) + products = list(/obj/item/weapon/storage/bag/tray = 8,/obj/item/weapon/kitchen/utensil/fork = 6,/obj/item/weapon/kitchenknife = 3,/obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 8,/obj/item/clothing/suit/chef/classic = 2,/obj/item/weapon/reagent_containers/food/condiment/pack/ketchup = 5,/obj/item/weapon/reagent_containers/food/condiment/pack/hotsauce = 5) contraband = list(/obj/item/weapon/kitchen/utensil/spoon = 2,/obj/item/weapon/kitchen/utensil/knife = 2,/obj/item/weapon/kitchen/rollingpin = 2, /obj/item/weapon/butch = 2) /obj/machinery/vending/sovietsoda @@ -979,8 +1085,8 @@ icon_state = "engivend" icon_deny = "engivend-deny" req_access_txt = "11" //Engineering Equipment access - products = list(/obj/item/clothing/glasses/meson = 2,/obj/item/device/multitool = 4,/obj/item/weapon/airlock_electronics = 10,/obj/item/weapon/module/power_control = 10,/obj/item/weapon/airalarm_electronics = 10,/obj/item/weapon/cell/high = 10) - contraband = list(/obj/item/weapon/cell/potato = 3) + products = list(/obj/item/clothing/glasses/meson = 2,/obj/item/device/multitool = 4,/obj/item/weapon/airlock_electronics = 10,/obj/item/weapon/module/power_control = 10,/obj/item/weapon/airalarm_electronics = 10,/obj/item/weapon/stock_parts/cell/high = 10) + contraband = list(/obj/item/weapon/stock_parts/cell/potato = 3) premium = list(/obj/item/weapon/storage/belt/utility = 3) //This one's from bay12 @@ -993,7 +1099,7 @@ products = list(/obj/item/clothing/under/rank/chief_engineer = 4,/obj/item/clothing/under/rank/engineer = 4,/obj/item/clothing/shoes/orange = 4,/obj/item/clothing/head/hardhat = 4, /obj/item/weapon/storage/belt/utility = 4,/obj/item/clothing/glasses/meson = 4,/obj/item/clothing/gloves/yellow = 4, /obj/item/weapon/screwdriver = 12, /obj/item/weapon/crowbar = 12,/obj/item/weapon/wirecutters = 12,/obj/item/device/multitool = 12,/obj/item/weapon/wrench = 12,/obj/item/device/t_scanner = 12, - /obj/item/stack/cable_coil/heavyduty = 8, /obj/item/weapon/cell = 8, /obj/item/weapon/weldingtool = 8,/obj/item/clothing/head/welding = 8, + /obj/item/stack/cable_coil/heavyduty = 8, /obj/item/weapon/stock_parts/cell = 8, /obj/item/weapon/weldingtool = 8,/obj/item/clothing/head/welding = 8, /obj/item/weapon/light/tube = 10,/obj/item/clothing/suit/fire = 4, /obj/item/weapon/stock_parts/scanning_module = 5,/obj/item/weapon/stock_parts/micro_laser = 5, /obj/item/weapon/stock_parts/matter_bin = 5,/obj/item/weapon/stock_parts/manipulator = 5,/obj/item/weapon/stock_parts/console_screen = 5) // There was an incorrect entry (cablecoil/power). I improvised to cablecoil/heavyduty. @@ -1008,7 +1114,7 @@ icon_deny = "robotics-deny" req_access_txt = "29" products = list(/obj/item/clothing/suit/storage/labcoat = 4,/obj/item/clothing/under/rank/roboticist = 4,/obj/item/stack/cable_coil = 4,/obj/item/device/flash = 4, - /obj/item/weapon/cell/high = 12, /obj/item/device/assembly/prox_sensor = 3,/obj/item/device/assembly/signaler = 3,/obj/item/device/healthanalyzer = 3, + /obj/item/weapon/stock_parts/cell/high = 12, /obj/item/device/assembly/prox_sensor = 3,/obj/item/device/assembly/signaler = 3,/obj/item/device/healthanalyzer = 3, /obj/item/weapon/scalpel = 2,/obj/item/weapon/circular_saw = 2,/obj/item/weapon/tank/anesthetic = 2,/obj/item/clothing/mask/breath/medical = 5, /obj/item/weapon/screwdriver = 5,/obj/item/weapon/crowbar = 5) //everything after the power cell had no amounts, I improvised. -Sayu @@ -1097,11 +1203,11 @@ /obj/item/clothing/under/pants/camo = 1,/obj/item/clothing/under/pants/blackjeans=2,/obj/item/clothing/under/pants/khaki=2, /obj/item/clothing/under/pants/white=2,/obj/item/clothing/under/pants/red=1,/obj/item/clothing/under/pants/black=2, /obj/item/clothing/under/pants/tan=2,/obj/item/clothing/under/pants/blue=1,/obj/item/clothing/under/pants/track=1, - /obj/item/clothing/tie/scarf/red=1,/obj/item/clothing/tie/scarf/green=1,/obj/item/clothing/tie/scarf/darkblue=1, - /obj/item/clothing/tie/scarf/purple=1,/obj/item/clothing/tie/scarf/yellow=1,/obj/item/clothing/tie/scarf/orange=1, - /obj/item/clothing/tie/scarf/lightblue=1,/obj/item/clothing/tie/scarf/white=1,/obj/item/clothing/tie/scarf/black=1, - /obj/item/clothing/tie/scarf/zebra=1,/obj/item/clothing/tie/scarf/christmas=1,/obj/item/clothing/tie/stripedredscarf=1, - /obj/item/clothing/tie/stripedbluescarf=1,/obj/item/clothing/tie/stripedgreenscarf=1,/obj/item/clothing/tie/waistcoat=1, + /obj/item/clothing/accessory/scarf/red=1,/obj/item/clothing/accessory/scarf/green=1,/obj/item/clothing/accessory/scarf/darkblue=1, + /obj/item/clothing/accessory/scarf/purple=1,/obj/item/clothing/accessory/scarf/yellow=1,/obj/item/clothing/accessory/scarf/orange=1, + /obj/item/clothing/accessory/scarf/lightblue=1,/obj/item/clothing/accessory/scarf/white=1,/obj/item/clothing/accessory/scarf/black=1, + /obj/item/clothing/accessory/scarf/zebra=1,/obj/item/clothing/accessory/scarf/christmas=1,/obj/item/clothing/accessory/stripedredscarf=1, + /obj/item/clothing/accessory/stripedbluescarf=1,/obj/item/clothing/accessory/stripedgreenscarf=1,/obj/item/clothing/accessory/waistcoat=1, /obj/item/clothing/under/sundress=2,/obj/item/clothing/under/stripeddress = 1, /obj/item/clothing/under/sailordress = 1, /obj/item/clothing/under/redeveninggown = 1, /obj/item/clothing/under/blacktango=1,/obj/item/clothing/suit/jacket=3, /obj/item/clothing/glasses/regular=2,/obj/item/clothing/head/sombrero=1,/obj/item/clothing/suit/poncho=1, /obj/item/clothing/suit/ianshirt=1,/obj/item/clothing/shoes/laceup=2,/obj/item/clothing/shoes/black=4, diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm index c72b2338cba..19108eec93d 100644 --- a/code/game/machinery/washing_machine.dm +++ b/code/game/machinery/washing_machine.dm @@ -151,7 +151,7 @@ if (S.chained == 1) S.chained = 0 S.slowdown = SHOES_SLOWDOWN - new /obj/item/weapon/handcuffs( src ) + new /obj/item/weapon/restraints/handcuffs( src ) S.icon_state = new_shoe_icon_state S._color = _color S.name = new_shoe_name @@ -194,7 +194,7 @@ /obj/machinery/washing_machine/update_icon() icon_state = "wm_[state][panel]" -/obj/machinery/washing_machine/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/washing_machine/attackby(obj/item/weapon/W as obj, mob/user as mob, params) /*if(istype(W,/obj/item/weapon/screwdriver)) panel = !panel user << "\blue you [panel ? "open" : "close"] the [src]'s maintenance panel"*/ diff --git a/code/game/machinery/wishgranter.dm b/code/game/machinery/wishgranter.dm index ac2986f18a2..22e89cfe000 100644 --- a/code/game/machinery/wishgranter.dm +++ b/code/game/machinery/wishgranter.dm @@ -30,52 +30,96 @@ insisting++ else - user << "You speak. [pick("I want the station to disappear","Humanity is corrupt, mankind must be destroyed","I want to be rich", "I want to rule the world","I want immortality.")]. The Wish Granter answers." - user << "Your head pounds for a moment, before your vision clears. You are the avatar of the Wish Granter, and your power is LIMITLESS! And it's all yours. You need to make sure no one can take it from you. No one can know, first." - - charges-- - insisting = 0 - - if (!(M_HULK in user.mutations)) - user.dna.SetSEState(HULKBLOCK,1) - - if (!(M_LASER in user.mutations)) - user.mutations.Add(M_LASER) - - if (!(M_XRAY in user.mutations)) - user.mutations.Add(M_XRAY) - user.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS) - user.see_in_dark = 8 - user.see_invisible = SEE_INVISIBLE_LEVEL_TWO - - if (!(M_RESIST_COLD in user.mutations)) - user.mutations.Add(M_RESIST_COLD) - - if (!(M_RESIST_HEAT in user.mutations)) - user.mutations.Add(M_RESIST_HEAT) - - if (!(M_TK in user.mutations)) - user.mutations.Add(M_TK) - - /* Not used - if(!(HEAL in user.mutations)) - user.mutations.Add(HEAL) - */ - - user.update_mutations() + user << "The power of the Wish Granter have turned you into the superhero the station deserves. You are a masked vigilante, and answer to no man. Will you use your newfound strength to protect the innocent, or will you hunt the guilty?" ticker.mode.traitors += user.mind - user.mind.special_role = "Avatar of the Wish Granter" + user.mind.special_role = "The Hero The Station Deserves" - var/datum/objective/silence/silence = new - silence.owner = user.mind - user.mind.objectives += silence + + var/mob/living/carbon/human/M = user + + var/wish = input("You want to...","Wish") as anything in list("Protect the innocent","Hunt the guilty") + switch(wish) + if("Protect the innocent") + M.fully_replace_character_name(M.real_name, "Owlman") + + var/datum/objective/protect/protect = new + protect.owner = user.mind + user.mind.objectives += protect + + for(var/obj/item/W in M) + M.unEquip(W) + + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/under/owl(M), slot_w_uniform) + M.equip_to_slot_or_del(new /obj/item/clothing/suit/toggle/owlwings(M), slot_wear_suit) + M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/owl_mask(M), slot_wear_mask) + + var/obj/item/weapon/card/id/syndicate/W = new(M) + W.name = "[M.real_name]'s ID Card (Superhero)" + W.access = get_all_accesses() + W.assignment = "Superhero" + W.registered_name = M.real_name + M.equip_to_slot_or_del(W, slot_wear_id) + + M.regenerate_icons() + + if("Hunt the guilty") + M.fully_replace_character_name(M.real_name, "The Griffin") + + var/datum/objective/assassinate/assasinate = new + assasinate.owner = user.mind + user.mind.objectives += assasinate + + for(var/obj/item/W in M) + M.unEquip(W) + + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/griffin(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/under/griffin(M), slot_w_uniform) + M.equip_to_slot_or_del(new /obj/item/clothing/suit/toggle/owlwings/griffinwings(M), slot_wear_suit) + M.equip_to_slot_or_del(new /obj/item/clothing/head/griffin(M), slot_head) + + var/obj/item/weapon/card/id/syndicate/W = new(M) + W.name = "[M.real_name]'s ID Card (Supervillain)" + W.access = get_all_accesses() + W.assignment = "Supervillain" + W.registered_name = M.real_name + M.equip_to_slot_or_del(W, slot_wear_id) + + M.regenerate_icons() var/obj_count = 1 for(var/datum/objective/OBJ in user.mind.objectives) user << "Objective #[obj_count]: [OBJ.explanation_text]" obj_count++ - user << "You have a very bad feeling about this." + charges-- + insisting = 0 + + if (!(HULK in user.mutations)) + user.dna.SetSEState(HULKBLOCK,1) + + if (!(LASER in user.mutations)) + user.mutations.Add(LASER) + + if (!(XRAY in user.mutations)) + user.mutations.Add(XRAY) + user.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS) + user.see_in_dark = 8 + user.see_invisible = SEE_INVISIBLE_LEVEL_TWO + + if (!(RESIST_COLD in user.mutations)) + user.mutations.Add(RESIST_COLD) + + if (!(RESIST_HEAT in user.mutations)) + user.mutations.Add(RESIST_HEAT) + + if (!(TK in user.mutations)) + user.mutations.Add(TK) + + if(!(REGEN in user.mutations)) + user.mutations.Add(REGEN) + + user.update_mutations() return \ No newline at end of file diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm index 2c723a2e530..26d9d066fd8 100644 --- a/code/game/mecha/combat/gygax.dm +++ b/code/game/mecha/combat/gygax.dm @@ -53,7 +53,7 @@ ME.attach(src) return -/obj/mecha/combat/gygax/dark/add_cell(var/obj/item/weapon/cell/C=null) +/obj/mecha/combat/gygax/dark/add_cell(var/obj/item/weapon/stock_parts/cell/C=null) if(C) C.forceMove(src) cell = C diff --git a/code/game/mecha/combat/marauder.dm b/code/game/mecha/combat/marauder.dm index c332603ab46..b5951d306c2 100644 --- a/code/game/mecha/combat/marauder.dm +++ b/code/game/mecha/combat/marauder.dm @@ -73,7 +73,7 @@ src.smoke_system.attach(src) return -/obj/mecha/combat/marauder/seraph/New() +/obj/mecha/combat/marauder/seraph/loaded/New() ..()//Let it equip whatever is needed. var/obj/item/mecha_parts/mecha_equipment/ME if(equipment.len)//Now to remove it and equip anew. diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm index cf3cd0022a6..c618ec8c72f 100644 --- a/code/game/mecha/equipment/tools/tools.dm +++ b/code/game/mecha/equipment/tools/tools.dm @@ -389,7 +389,7 @@ range = RANGED action(atom/target) - if(!action_checks(target) || src.loc.z == 2) return + if(!action_checks(target) || (src.loc.z in config.admin_levels)) return var/turf/T = get_turf(target) if(T) set_ready_state(0) @@ -410,7 +410,7 @@ action(atom/target) - if(!action_checks(target) || src.loc.z == 2) return + if(!action_checks(target) || (src.loc.z in config.admin_levels)) return var/list/theareas = list() for(var/area/AR in orange(100, chassis)) if(AR in theareas) continue @@ -548,9 +548,9 @@ if(!chassis) return return "* [src.name]" - proc/dynattackby(obj/item/weapon/W as obj, mob/user as mob) + proc/dynattackby(obj/item/weapon/W as obj, mob/user as mob, params) if(!action_checks(user)) - return chassis.dynattackby(W,user) + return chassis.dynattackby(W,user, params) chassis.log_message("Attacked by [W]. Attacker - [user]") if(prob(chassis.deflect_chance*deflect_coeff)) user << "\red The [W] bounces off [chassis] armor." @@ -920,7 +920,7 @@ return 0 return - attackby(weapon,mob/user) + attackby(weapon,mob/user, params) var/result = load_fuel(weapon) if(isnull(result)) user.visible_message("[user] tries to shove [weapon] into [src]. What a dumb-ass.","[fuel] traces minimal. [weapon] cannot be used as fuel.") diff --git a/code/game/mecha/equipment/tools/unused_tools.dm b/code/game/mecha/equipment/tools/unused_tools.dm index 68578913813..50fcc9d62bb 100644 --- a/code/game/mecha/equipment/tools/unused_tools.dm +++ b/code/game/mecha/equipment/tools/unused_tools.dm @@ -129,11 +129,11 @@ chassis.proc_res["dynattackby"] = src return - proc/dynattackby(obj/item/weapon/W as obj, mob/user as mob) + proc/dynattackby(obj/item/weapon/W as obj, mob/user as mob, params) if(!action_checks(user) || !active) return user.electrocute_act(shock_damage, src) - return chassis.dynattackby(W,user) + return chassis.dynattackby(W,user, params) /* diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index a4c8b5a527a..fc8c5ee658a 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -158,7 +158,7 @@ var/mob/living/carbon/human/H = M if(isobj(H.shoes)) var/thingy = H.shoes - H.drop_from_inventory(H.shoes) + H.unEquip(H.shoes) walk_away(thingy,chassis,15,2) spawn(20) if(thingy) diff --git a/code/game/mecha/mech_bay.dm b/code/game/mecha/mech_bay.dm index 59883f8b8df..8de93482907 100644 --- a/code/game/mecha/mech_bay.dm +++ b/code/game/mecha/mech_bay.dm @@ -37,7 +37,7 @@ component_parts += new /obj/item/weapon/stock_parts/capacitor(src) component_parts += new /obj/item/stack/cable_coil(src, 1) RefreshParts() - recharging_turf = get_step(loc, dir) + locate_recharge_turf() /obj/machinery/mech_bay_recharge_port/upgraded/New() ..() @@ -51,6 +51,9 @@ component_parts += new /obj/item/stack/cable_coil(src, 1) RefreshParts() +/obj/machinery/mech_bay_recharge_port/proc/locate_recharge_turf() + recharging_turf = get_step(loc, dir) + /obj/machinery/mech_bay_recharge_port/RefreshParts() var/MC for(var/obj/item/weapon/stock_parts/capacitor/C in component_parts) @@ -76,12 +79,12 @@ recharge_console.update_icon() -/obj/machinery/mech_bay_recharge_port/attackby(obj/item/I, mob/user) +/obj/machinery/mech_bay_recharge_port/attackby(obj/item/I, mob/user, params) if(default_deconstruction_screwdriver(user, "recharge_port-o", "recharge_port", I)) return if(default_change_direction_wrench(user, I)) - recharging_turf = get_step(loc, dir) + locate_recharge_turf() return if(exchange_parts(user, I)) diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 5b7a50c8594..e69394432be 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -498,7 +498,7 @@ return result -/obj/machinery/mecha_part_fabricator/attackby(obj/W as obj, mob/user as mob) +/obj/machinery/mecha_part_fabricator/attackby(obj/W as obj, mob/user as mob, params) if(default_deconstruction_screwdriver(user, "fab-o", "fab-idle", W)) return @@ -513,10 +513,7 @@ return 1 else user << "You can't load \the [name] while it's opened." - return 1 - - if(istype(W,/obj/item/weapon/card/emag)) - emag() + return 1 if(istype(W, /obj/item/stack)) var/material @@ -561,6 +558,9 @@ else user << "\The [src] cannot hold any more [sname] sheet\s." return + +/obj/machinery/mecha_part_fabricator/emag_act(user as mob) + emag() /obj/machinery/mecha_part_fabricator/proc/material2name(var/ID) return copytext(ID,2) \ No newline at end of file diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index d34d2bb0f2e..8633d1c871f 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -29,7 +29,7 @@ var/deflect_chance = 10 //chance to deflect the incoming projectiles, hits, or lesser the effect of ex_act. //the values in this list show how much damage will pass through, not how much will be absorbed. var/list/damage_absorption = list("brute"=0.8,"fire"=1.2,"bullet"=0.9,"laser"=1,"energy"=1,"bomb"=1) - var/obj/item/weapon/cell/cell + var/obj/item/weapon/stock_parts/cell/cell var/state = 0 var/list/log = new var/last_message = 0 @@ -115,7 +115,7 @@ internal_tank = new /obj/machinery/portable_atmospherics/canister/air(src) return internal_tank -/obj/mecha/proc/add_cell(var/obj/item/weapon/cell/C=null) +/obj/mecha/proc/add_cell(var/obj/item/weapon/stock_parts/cell/C=null) if(C) C.forceMove(src) cell = C @@ -453,7 +453,9 @@ src.destroy() return -/obj/mecha/attack_hand(mob/user as mob) +/obj/mecha/attack_hand(mob/living/user as mob) + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) src.log_message("Attack by hand/paw. Attacker - [user].",1) if(ishuman(user)) @@ -461,7 +463,7 @@ call(/obj/item/clothing/gloves/space_ninja/proc/drain)("MECHA",src,user:wear_suit) return - if ((M_HULK in user.mutations) && !prob(src.deflect_chance)) + if ((HULK in user.mutations) && !prob(src.deflect_chance)) src.take_damage(15) src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) user.visible_message("[user] hits [src.name], doing some damage.", "You hit [src.name] with all your might. The metal creaks and bends.") @@ -470,12 +472,14 @@ src.log_append_to_last("Armor saved.") return -/obj/mecha/attack_paw(mob/user as mob) +/obj/mecha/attack_paw(mob/living/user as mob) return src.attack_hand(user) -/obj/mecha/attack_alien(mob/user as mob) +/obj/mecha/attack_alien(mob/living/user as mob) src.log_message("Attack by alien. Attacker - [user].",1) + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) if(!prob(src.deflect_chance)) src.take_damage(15) src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) @@ -496,6 +500,7 @@ if(user.melee_damage_upper == 0) user.emote("[user.friendly] [src]") else + user.do_attack_animation(src) if(!prob(src.deflect_chance)) var/damage = rand(user.melee_damage_lower, user.melee_damage_upper) src.take_damage(damage) @@ -674,8 +679,10 @@ src.check_for_internal_damage(list(MECHA_INT_FIRE, MECHA_INT_TEMP_CONTROL)) return -/obj/mecha/proc/dynattackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/mecha/proc/dynattackby(obj/item/weapon/W as obj, mob/living/user as mob, params) src.log_message("Attacked by [W]. Attacker - [user]") + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) if(prob(src.deflect_chance)) user << "\red The [W] bounces off [src.name] armor." src.log_append_to_last("Armor saved.") @@ -695,18 +702,7 @@ ////// AttackBy ////// ////////////////////// -/obj/mecha/attackby(obj/item/weapon/W as obj, mob/user as mob) - - if(istype(W, /obj/item/weapon/card/emag)) - if(istype(src, /obj/mecha/working/ripley) && emagged == 0) - emagged = 1 - usr << "\blue You slide the [W] through the [src]'s ID slot." - playsound(src.loc, "sparks", 100, 1) - src.desc += "
    \red The mech's equiptment slots spark dangerously!" - else - usr <<"\red The [src]'s ID slot rejects the [W]." - return - +/obj/mecha/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/device/mmi) || istype(W, /obj/item/device/mmi/posibrain)) if(mmi_move_inside(W,user)) @@ -781,7 +777,7 @@ user << "You screw the cell in place" return - else if(istype(W, /obj/item/weapon/cell)) + else if(istype(W, /obj/item/weapon/stock_parts/cell)) if(state==4) if(!src.cell) user << "You install the powercell" @@ -809,7 +805,9 @@ return else if(istype(W, /obj/item/mecha_parts/mecha_tracking)) - user.drop_from_inventory(W) + if(!user.unEquip(W)) + user << "\the [W] is stuck to your hand, you cannot put it in \the [src]" + return W.forceMove(src) user.visible_message("[user] attaches [W] to [src].", "You attach [W] to [src]") return @@ -862,6 +860,15 @@ */ return +/obj/mecha/emag_act(user as mob) + if(istype(src, /obj/mecha/working/ripley) && emagged == 0) + emagged = 1 + usr << "\blue You slide the card through the [src]'s ID slot." + playsound(src.loc, "sparks", 100, 1) + src.desc += "
    \red The mech's equiptment slots spark dangerously!" + else + usr <<"\red The [src]'s ID slot rejects the card." + return /* @@ -1118,7 +1125,9 @@ else if(mmi_as_oc.brainmob.stat) user << "Beta-rhythm below acceptable level." return 0 - user.drop_from_inventory(mmi_as_oc) + if(!user.unEquip(mmi_as_oc)) + user << "\the [mmi_as_oc] is stuck to your hand, you cannot put it in \the [src]" + return var/mob/brainmob = mmi_as_oc.brainmob brainmob.reset_view(src) /* @@ -1231,6 +1240,8 @@ ///////////////////////// /obj/mecha/proc/operation_allowed(mob/living/carbon/human/H) + if(!ishuman(H)) + return 0 for(var/ID in list(H.get_active_hand(), H.wear_id, H.belt)) if(src.check_access(ID,src.operation_req_access)) return 1 diff --git a/code/game/mecha/mecha_construction_paths.dm b/code/game/mecha/mecha_construction_paths.dm index 37e1c1ee13e..223f6d4aa24 100644 --- a/code/game/mecha/mecha_construction_paths.dm +++ b/code/game/mecha/mecha_construction_paths.dm @@ -91,7 +91,7 @@ const_holder.icon_state = "ripley0" const_holder.density = 1 const_holder.overlays.len = 0 - qdel(src) + del(src) return diff --git a/code/game/mecha/mecha_parts.dm b/code/game/mecha/mecha_parts.dm index 58b2d2215ce..6237bcfd523 100644 --- a/code/game/mecha/mecha_parts.dm +++ b/code/game/mecha/mecha_parts.dm @@ -7,7 +7,7 @@ icon = 'icons/mecha/mech_construct.dmi' icon_state = "blank" w_class = 6 - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT origin_tech = "programming=2;materials=2" var/construction_time = 100 var/list/construction_cost = list("metal"=20000,"glass"=5000) @@ -18,9 +18,9 @@ icon_state = "backbone" var/datum/construction/construct construction_cost = list("metal"=20000) - flags = FPRINT | CONDUCT + flags = CONDUCT - attackby(obj/item/W as obj, mob/user as mob) + attackby(obj/item/W as obj, mob/user as mob, params) if(!construct || !construct.action(W, user)) ..() return @@ -409,7 +409,7 @@ icon_state = "std_mod" item_state = "electronic" board_type = "other" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT force = 5.0 w_class = 2.0 throwforce = 5.0 diff --git a/code/game/mecha/mecha_wreckage.dm b/code/game/mecha/mecha_wreckage.dm index 62c8c7c5d47..b2c4b0bc0db 100644 --- a/code/game/mecha/mecha_wreckage.dm +++ b/code/game/mecha/mecha_wreckage.dm @@ -30,7 +30,7 @@ return -/obj/effect/decal/mecha_wreckage/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/effect/decal/mecha_wreckage/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/WT = W if(salvage_num <= 0) diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm index c3a05eae825..985b3bca9ba 100644 --- a/code/game/objects/effects/aliens.dm +++ b/code/game/objects/effects/aliens.dm @@ -101,7 +101,8 @@ /obj/structure/alien/resin/attack_hand(mob/living/user) - if(M_HULK in user.mutations) + if(HULK in user.mutations) + user.do_attack_animation(src) user.visible_message("[user] destroys [src]!") health = 0 healthcheck() @@ -112,6 +113,8 @@ /obj/structure/alien/resin/attack_alien(mob/living/user) + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) if(islarva(user)) return user.visible_message("[user] claws at the resin!") @@ -122,7 +125,8 @@ healthcheck() -/obj/structure/alien/resin/attackby(obj/item/I, mob/living/user) +/obj/structure/alien/resin/attackby(obj/item/I, mob/living/user, params) + user.changeNext_move(CLICK_CD_MELEE) health -= I.force playsound(loc, 'sound/effects/attackblob.ogg', 100, 1) healthcheck() @@ -202,7 +206,8 @@ del(src) -/obj/structure/alien/weeds/attackby(obj/item/I, mob/user) +/obj/structure/alien/weeds/attackby(obj/item/I, mob/user, params) + user.changeNext_move(CLICK_CD_MELEE) if(I.attack_verb.len) visible_message("[user] has [pick(I.attack_verb)] [src] with [I]!") else @@ -355,7 +360,8 @@ healthcheck() -/obj/structure/alien/egg/attackby(obj/item/I, mob/user) +/obj/structure/alien/egg/attackby(obj/item/I, mob/user, params) + user.changeNext_move(CLICK_CD_MELEE) if(I.attack_verb.len) visible_message("[user] has [pick(I.attack_verb)] [src] with [I]!") else diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm index 2a0235652ac..a0b3fff9c7b 100644 --- a/code/game/objects/effects/anomalies.dm +++ b/code/game/objects/effects/anomalies.dm @@ -35,7 +35,7 @@ qdel(src) -/obj/effect/anomaly/attackby(obj/item/I, mob/user) +/obj/effect/anomaly/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/device/analyzer)) user << "Analyzing... [src]'s unstable field is fluctuating along frequency [aSignal.code]:[format_frequency(aSignal.frequency)]." diff --git a/code/game/objects/effects/decals/contraband.dm b/code/game/objects/effects/decals/contraband.dm index d32c2b9b7e1..7f3de1cf8c6 100644 --- a/code/game/objects/effects/decals/contraband.dm +++ b/code/game/objects/effects/decals/contraband.dm @@ -48,7 +48,7 @@ obj/structure/sign/poster/New(var/serial) icon_state = design.icon_state // poster[serial_number] ..() -obj/structure/sign/poster/attackby(obj/item/weapon/W as obj, mob/user as mob) +obj/structure/sign/poster/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/wirecutters)) playsound(loc, 'sound/items/Wirecutter.ogg', 100, 1) if(ruined) @@ -89,7 +89,7 @@ obj/structure/sign/poster/attackby(obj/item/weapon/W as obj, mob/user as mob) del(src) -//seperated to reduce code duplication. Moved here for ease of reference and to unclutter r_wall/attackby() +//seperated to reduce code duplication. Moved here for ease of reference and to unclutter r_wall/attackby(, params) /turf/simulated/wall/proc/place_poster(var/obj/item/weapon/contraband/poster/P, var/mob/user) if(!istype(src,/turf/simulated/wall)) diff --git a/code/game/objects/effects/decals/posters/tgposters.dm b/code/game/objects/effects/decals/posters/tgposters.dm index 2605bfaf20f..6fa936d4ca6 100644 --- a/code/game/objects/effects/decals/posters/tgposters.dm +++ b/code/game/objects/effects/decals/posters/tgposters.dm @@ -103,3 +103,13 @@ name = "Borg Fancy v2" desc = "Borg Fancy, Now only taking the most fancy." icon_state="poster21" + +/datum/poster/tg_22 + name = "The Griffin" + desc = " The Griffin commands you to be the worst you can be. Will you?" + icon_state="poster22" + +/datum/poster/tg_23 + name = "The Owl" + desc = " The Owl would do his best to protect the station. Will you?" + icon_state="poster23" \ No newline at end of file diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index 27db5475d94..73ccbd3aab3 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -11,14 +11,23 @@ would spawn and follow the beaker, even if it is carried or thrown. icon = 'icons/effects/effects.dmi' mouse_opacity = 0 unacidable = 1//So effect are not targeted by alien acid. - flags = TABLEPASS + +/datum/effect/effect/proc/fadeOut(var/atom/A, var/frames = 16) + if(A.alpha == 0) //Handle already transparent case + return + if(frames == 0) + frames = 1 //We will just assume that by 0 frames, the coder meant "during one frame". + var/step = A.alpha / frames + for(var/i = 0, i < frames, i++) + A.alpha -= step + sleep(world.tick_lag) + return /obj/effect/effect/water name = "water" icon = 'icons/effects/effects.dmi' icon_state = "extinguish" var/life = 15.0 - flags = TABLEPASS mouse_opacity = 0 /obj/effect/effect/smoke @@ -183,36 +192,40 @@ steam.start() -- spawns the effect return /datum/effect/effect/system/spark_spread - set_up(n = 3, c = 0, loca) - number = n > 10 ? 10 : n - cardinals = c + var/total_sparks = 0 // To stop it being spammed and lagging! - if (istype(loca, /turf/)) + set_up(n = 3, c = 0, loca) + if(n > 10) + n = 10 + number = n + cardinals = c + if(istype(loca, /turf/)) location = loca else location = get_turf(loca) start() - for (var/i = 1 to number) - spawn() - if (holder) - location = get_turf(holder) - - var/obj/effect/effect/sparks/sparks = getFromPool(/obj/effect/effect/sparks, location) - playsound(location, "sparks", 100, 1) + var/i = 0 + for(i=0, i 20) + return + spawn(0) + if(holder) + src.location = get_turf(holder) + var/obj/effect/effect/sparks/sparks = new /obj/effect/effect/sparks(src.location) + src.total_sparks++ var/direction - - if (cardinals) + if(src.cardinals) direction = pick(cardinal) else direction = pick(alldirs) - - for (var/j = 0, j < pick(1, 2, 3), j++) + for(i=0, i 0) - devastation = min (MAX_EXPLOSION_RANGE, devastation + round(amount/12)) + devastation = min (MAX_EX_DEVESTATION_RANGE, devastation + round(amount/12)) if (round(amount/6) > 0) - heavy = min (MAX_EXPLOSION_RANGE, heavy + round(amount/6)) + heavy = min (MAX_EX_HEAVY_RANGE, heavy + round(amount/6)) if (round(amount/3) > 0) - light = min (MAX_EXPLOSION_RANGE, light + round(amount/3)) + light = min (MAX_EX_LIGHT_RANGE, light + round(amount/3)) if (flash && flashing_factor) flash += (round(amount/4) * flashing_factor) diff --git a/code/game/objects/effects/glowshroom.dm b/code/game/objects/effects/glowshroom.dm index 61ab55b4c68..e8b8cc4bdaf 100644 --- a/code/game/objects/effects/glowshroom.dm +++ b/code/game/objects/effects/glowshroom.dm @@ -133,7 +133,7 @@ floor = 1 return 1 -/obj/effect/glowshroom/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/effect/glowshroom/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() endurance -= W.force diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index 1963e2fb29a..a040e460b2c 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -32,4 +32,10 @@ /obj/effect/overlay/coconut name = "Coconuts" icon = 'icons/misc/beach.dmi' - icon_state = "coconuts" \ No newline at end of file + icon_state = "coconuts" + +/obj/effect/overlay/adminoverlay + name = "adminoverlay" + icon = 'icons/effects/effects.dmi' + icon_state = "admin" + layer = 4.1 diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index e11b35ac207..62a9bb7a57b 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -20,7 +20,7 @@ qdel(src) return -/obj/effect/spider/attackby(var/obj/item/weapon/W, var/mob/user) +/obj/effect/spider/attackby(var/obj/item/weapon/W, var/mob/user, params) if(W.attack_verb.len) visible_message("\red \The [src] have been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]") else diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index cedc2e47cd8..399455d208c 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -5,13 +5,11 @@ var/no_embed = 0 // For use in item_attack.dm var/icon/blood_overlay = null //this saves our blood splatter overlay, which will be processed not to go over the edges of the sprite var/blood_overlay_color = null - var/abstract = 0 var/item_state = null var/r_speed = 1.0 var/health = null var/hitsound = null var/w_class = 3.0 - flags = FPRINT | TABLEPASS var/slot_flags = 0 //This is used to determine on which slots an item can fit. pass_flags = PASSTABLE pressure_resistance = 5 @@ -35,7 +33,6 @@ var/permeability_coefficient = 1 // for chemicals/diseases var/siemens_coefficient = 1 // for electrical admittance/conductance (electrocution checks and shit) var/slowdown = 0 // How much clothing is slowing you down. Negative values speeds you up - var/canremove = 1 //Mostly for Ninja code at this point but basically will not allow the item to be removed if set to 0. /N var/reflect_chance = 0 //This var dictates what % of a time an object will reflect an energy based weapon's shot var/armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) var/list/allowed = null //suit storage stuff. @@ -56,7 +53,7 @@ /obj/item/Destroy() if(istype(src.loc, /mob)) var/mob/H = src.loc - H.drop_from_inventory(src) // items at the very least get unequipped from their mob before being deleted + H.unEquip(src) // items at the very least get unequipped from their mob before being deleted if(reagents && istype(reagents)) reagents.my_atom = null reagents.delete() @@ -129,7 +126,7 @@ if(5.0) size = "huge" else - //if ((M_CLUMSY in usr.mutations) && prob(50)) t = "funny-looking" + //if ((CLUMSY in usr.mutations) && prob(50)) t = "funny-looking" usr << "This is a [src.blood_DNA ? "bloody " : ""]\icon[src][src.name]. It is a [size] item." if(src.desc) usr << src.desc @@ -151,19 +148,15 @@ S.remove_from_storage(src) src.throwing = 0 - if (src.loc == user) - //canremove==0 means that object may not be removed. You can still wear it. This only applies to clothing. /N - if(!src.canremove) + if (loc == user) + if(!user.unEquip(src)) return 0 - else - user.u_equip(src) else - if(isliving(src.loc)) + if(isliving(loc)) return 0 - user.next_move = max(user.next_move+2,world.time + 2) - src.pickup(user) + pickup(user) add_fingerprint(user) user.put_in_active_hand(src) return 1 @@ -176,7 +169,7 @@ if(!A.has_fine_manipulation || w_class >= 4) if(src in A.contents) // To stop Aliens having items stuck in their pockets - A.drop_from_inventory(src) + A.unEquip(src) user << "Your claws aren't capable of such fine manipulation." return @@ -187,16 +180,12 @@ M.client.screen -= src src.throwing = 0 if (src.loc == user) - //canremove==0 means that object may not be removed. You can still wear it. This only applies to clothing. /N - if(istype(src, /obj/item/clothing) && !src:canremove) + if(!user.unEquip(src)) return - else - user.u_equip(src) else if(istype(src.loc, /mob/living)) return src.pickup(user) - user.next_move = max(user.next_move+2,world.time + 2) user.put_in_active_hand(src) return @@ -207,7 +196,7 @@ if(!A.has_fine_manipulation || w_class >= 4) if(src in A.contents) // To stop Aliens having items stuck in their pockets - A.drop_from_inventory(src) + A.unEquip(src) user << "Your claws aren't capable of such fine manipulation." return attack_paw(A) @@ -222,7 +211,7 @@ // Due to storage type consolidation this should get used more now. // I have cleaned it up a little, but it could probably use more. -Sayu -/obj/item/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/storage)) var/obj/item/weapon/storage/S = W if(S.use_to_pickup) @@ -311,7 +300,7 @@ if(istype(src, /obj/item/clothing/under) || istype(src, /obj/item/clothing/suit)) - if(M_FAT in H.mutations) + if(FAT in H.mutations) testing("[M] TOO FAT TO WEAR [src]!") if(!(flags & ONESIZEFITSALL)) if(!disable_warning) @@ -422,6 +411,8 @@ return 0 return 1 if(slot_l_store) + if(flags & NODROP) //Pockets aren't visible, so you can't move NODROP items into them. + return 0 if(H.l_store) return 0 if(!H.w_uniform) @@ -433,6 +424,8 @@ if( w_class <= 2 || (slot_flags & SLOT_POCKET) ) return 1 if(slot_r_store) + if(flags & NODROP) + return 0 if(H.r_store) return 0 if(!H.w_uniform) @@ -445,6 +438,8 @@ return 1 return 0 if(slot_s_store) + if(flags & NODROP) //Suit storage NODROP items drop if you take a suit off, this is to prevent people exploiting this. + return 0 if(H.s_store) return 0 if(!H.wear_suit) @@ -465,13 +460,13 @@ if(slot_handcuffed) if(H.handcuffed) return 0 - if(!istype(src, /obj/item/weapon/handcuffs)) + if(!istype(src, /obj/item/weapon/restraints/handcuffs)) return 0 return 1 if(slot_legcuffed) if(H.legcuffed) return 0 - if(!istype(src, /obj/item/weapon/legcuffs)) + if(!istype(src, /obj/item/weapon/restraints/legcuffs)) return 0 return 1 if(slot_in_backpack) @@ -480,6 +475,19 @@ if(B.contents.len < B.storage_slots && w_class <= B.max_w_class) return 1 return 0 + if(slot_tie) + if(!H.w_uniform) + if(!disable_warning) + H << "You need a jumpsuit before you can attach this [name]." + return 0 + var/obj/item/clothing/under/uniform = H.w_uniform + if(uniform.accessories.len && !uniform.can_attach_accessory(src)) + if (!disable_warning) + H << "You already have an accessory of this type attached to your [uniform]." + return 0 + if( !(slot_flags & SLOT_TIE) ) + return 0 + return 1 return 0 //Unsupported slot //END HUMAN @@ -551,7 +559,7 @@ if( src in usr ) attack_self(usr) return - else if(istype(src, /obj/item/clothing/tie)) + else if(istype(src, /obj/item/clothing/accessory)) if(istype(src.loc,/obj/item/clothing/under)) attack_self(usr) @@ -604,7 +612,7 @@ M.LAssailant = user src.add_fingerprint(user) - //if((M_CLUMSY in user.mutations) && prob(50)) + //if((CLUMSY in user.mutations) && prob(50)) // M = user /* M << "\red You stab yourself in the eye." diff --git a/code/game/objects/items/apc_frame.dm b/code/game/objects/items/apc_frame.dm index f2e760a34a5..764be72b131 100644 --- a/code/game/objects/items/apc_frame.dm +++ b/code/game/objects/items/apc_frame.dm @@ -5,9 +5,9 @@ desc = "Used for repairing or building APCs" icon = 'icons/obj/apc_repair.dmi' icon_state = "apc_frame" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT -/obj/item/apc_frame/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/apc_frame/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if (istype(W, /obj/item/weapon/wrench)) new /obj/item/stack/sheet/metal( get_turf(src.loc), 2 ) diff --git a/code/game/objects/items/ashtray.dm b/code/game/objects/items/ashtray.dm index 5ec88ac8bdf..bf554463a42 100644 --- a/code/game/objects/items/ashtray.dm +++ b/code/game/objects/items/ashtray.dm @@ -14,14 +14,14 @@ src.pixel_x = rand(-6, 6) return -/obj/item/ashtray/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/ashtray/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (health < 1) return if (istype(W,/obj/item/weapon/cigbutt) || istype(W,/obj/item/clothing/mask/cigarette) || istype(W, /obj/item/weapon/match)) if (contents.len >= max_butts) user << "This ashtray is full." return - user.u_equip(W) + user.unEquip(W) W.loc = src if (istype(W,/obj/item/clothing/mask/cigarette)) diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index 3ff89c5fd60..8eaf699205d 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -40,14 +40,14 @@ density = 0 - attackby(W as obj, mob/user as mob) + attackby(W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/pen)) var/t = input(user, "What would you like the label to be?", text("[]", src.name), null) as text if (user.get_active_hand() != W) return if (!in_range(src, user) && src.loc != user) return - t = copytext(sanitize(t),1,MAX_MESSAGE_LEN) + t = sanitize(copytext(t,1,MAX_MESSAGE_LEN)) if (t) src.name = "body bag - " src.name += t @@ -127,7 +127,7 @@ usr << "\red You can't fold that up anymore.." ..() - attackby(W as obj, mob/user as mob) + attackby(W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/device/pda)) if(src.allowed(user)) src.locked = !src.locked diff --git a/code/game/objects/items/candle.dm b/code/game/objects/items/candle.dm index b47a2a30684..a68258e6a1c 100644 --- a/code/game/objects/items/candle.dm +++ b/code/game/objects/items/candle.dm @@ -22,7 +22,7 @@ icon_state = "candle[i][lit ? "_lit" : ""]" - attackby(obj/item/weapon/W as obj, mob/user as mob) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if(istype(W, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/WT = W @@ -59,7 +59,8 @@ if(!wax) new/obj/item/trash/candle(src.loc) if(istype(src.loc, /mob)) - src.dropped() + var/mob/M = src.loc + M.unEquip(src, 1) //src is being deleted anyway del(src) update_icon() if(istype(loc, /turf)) //start a fire if possible diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 826de6fd4c4..914ec7d6be0 100755 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -11,7 +11,6 @@ var/global/list/obj/item/device/pda/PDAs = list() icon_state = "pda" item_state = "electronic" w_class = 1.0 - flags = FPRINT | TABLEPASS slot_flags = SLOT_PDA | SLOT_BELT //Main variables @@ -51,6 +50,7 @@ var/global/list/obj/item/device/pda/PDAs = list() var/obj/item/weapon/card/id/id = null //Making it possible to slot an ID card into the PDA so it can function as both. var/ownjob = null //related to above + var/ownrank = null // this one is rank, never alt title var/obj/item/device/paicard/pai = null // A slot for a personal AI device @@ -129,15 +129,15 @@ var/global/list/obj/item/device/pda/PDAs = list() icon_state = "pda-captain" detonate = 0 //toff = 1 - + /obj/item/device/pda/heads/ntrep default_cartridge = /obj/item/weapon/cartridge/supervisor icon_state = "pda-h" - + /obj/item/device/pda/heads/magistrate default_cartridge = /obj/item/weapon/cartridge/supervisor icon_state = "pda-h" - + /obj/item/device/pda/heads/blueshield default_cartridge = /obj/item/weapon/cartridge/hos icon_state = "pda-h" @@ -204,7 +204,7 @@ var/global/list/obj/item/device/pda/PDAs = list() /obj/item/device/pda/geneticist default_cartridge = /obj/item/weapon/cartridge/medical icon_state = "pda-genetics" - + /obj/item/device/pda/centcom default_cartridge = /obj/item/weapon/cartridge/centcom icon_state = "pda-h" @@ -217,9 +217,13 @@ var/global/list/obj/item/device/pda/PDAs = list() detonate = 0 -/obj/item/device/pda/ai/proc/set_name_and_job(newname as text, newjob as text) +/obj/item/device/pda/ai/proc/set_name_and_job(newname as text, newjob as text, newrank as null|text) owner = newname ownjob = newjob + if(newrank) + ownrank = newrank + else + ownrank = ownjob name = newname + " (" + ownjob + ")" @@ -575,6 +579,7 @@ var/global/list/obj/item/device/pda/PDAs = list() id_check(U, 1) if("UpdateInfo") ownjob = id.assignment + ownrank = id.rank name = "PDA-[owner] ([ownjob])" if("Eject")//Ejects the cart, only done from hub. if (!isnull(cartridge)) @@ -684,7 +689,7 @@ var/global/list/obj/item/device/pda/PDAs = list() U << "The PDA softly beeps." ui.close() else - t = copytext(sanitize(t), 1, 20) + t = sanitize(copytext(t, 1, 20)) ttone = t else ui.close() @@ -892,7 +897,7 @@ var/global/list/obj/item/device/pda/PDAs = list() /obj/item/device/pda/proc/create_message(var/mob/living/U = usr, var/obj/item/device/pda/P) var/t = input(U, "Please enter message", name, null) as text - t = copytext(sanitize(t), 1, MAX_MESSAGE_LEN) + t = sanitize(copytext(t, 1, MAX_MESSAGE_LEN)) t = readd_quotes(t) if (!t || !istype(P)) return @@ -1050,7 +1055,7 @@ var/global/list/obj/item/device/pda/PDAs = list() return // access to status display signals -/obj/item/device/pda/attackby(obj/item/C as obj, mob/user as mob) +/obj/item/device/pda/attackby(obj/item/C as obj, mob/user as mob, params) ..() if(istype(C, /obj/item/weapon/cartridge) && !cartridge) cartridge = C @@ -1069,6 +1074,7 @@ var/global/list/obj/item/device/pda/PDAs = list() if(!owner) owner = idcard.registered_name ownjob = idcard.assignment + ownrank = idcard.rank name = "PDA-[owner] ([ownjob])" user << "Card scanned." else diff --git a/code/game/objects/items/devices/PDA/radio.dm b/code/game/objects/items/devices/PDA/radio.dm index 63f1082884f..e3ea25af4e4 100644 --- a/code/game/objects/items/devices/PDA/radio.dm +++ b/code/game/objects/items/devices/PDA/radio.dm @@ -48,6 +48,8 @@ signal.data[key4] = value4 frequency.post_signal(src, signal, filter = s_filter) + + return /obj/item/radio/integrated/receive_signal(datum/signal/signal) /*var/obj/item/device/pda/P = src.loc diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index 7816473110e..144b920631c 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -4,7 +4,6 @@ icon_state = "aicard" // aicard-full item_state = "electronic" w_class = 2.0 - flags = FPRINT | TABLEPASS slot_flags = SLOT_BELT var/flush = null origin_tech = "programming=4;materials=4" @@ -137,4 +136,4 @@ if(2.0) if(prob(50)) del(src) if(3.0) - if(prob(25)) del(src) + if(prob(25)) del(src) diff --git a/code/game/objects/items/devices/autopsy.dm b/code/game/objects/items/devices/autopsy.dm index 8c5fbf7661e..67a424a309f 100644 --- a/code/game/objects/items/devices/autopsy.dm +++ b/code/game/objects/items/devices/autopsy.dm @@ -7,7 +7,7 @@ desc = "Extracts information on wounds." icon = 'icons/obj/autopsy_scanner.dmi' icon_state = "" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT w_class = 1.0 origin_tech = "materials=1;biotech=1" var/list/datum/autopsy_data_scanner/wdata = list() diff --git a/code/game/objects/items/devices/camera_bug.dm b/code/game/objects/items/devices/camera_bug.dm new file mode 100644 index 00000000000..057cdb765fc --- /dev/null +++ b/code/game/objects/items/devices/camera_bug.dm @@ -0,0 +1,371 @@ +#define VANILLA_BUG 0 +#define UNIVERSAL_BUG 1 +#define NETWORK_BUG 2 +#define SABOTAGE_BUG 3 +#define ADVANCED_BUG 4 +#define ADMIN_BUG 5 + +#define BUGMODE_LIST 0 +#define BUGMODE_MONITOR 1 +#define BUGMODE_TRACK 2 + + + +/obj/item/device/camera_bug + name = "camera bug" + desc = "For illicit snooping through the camera network." + icon = 'icons/obj/device.dmi' + icon_state = "camera_bug" + w_class = 1.0 + item_state = "camera_bug" + icon_override = 'icons/mob/in-hand/tools.dmi' + throw_speed = 4 + throw_range = 20 + + var/obj/machinery/camera/current = null + var/obj/item/expansion = null + var/bugtype = VANILLA_BUG + + var/last_net_update = 0 + var/last_bugtype = VANILLA_BUG + var/list/bugged_cameras = list() + var/skip_bugcheck = 0 + + var/track_mode = BUGMODE_LIST + var/last_tracked = 0 + var/refresh_interval = 50 + + var/tracked_name = null + var/atom/tracking = null + + var/last_found = null + var/last_seen = null + +/obj/item/device/camera_bug/New() + ..() + processing_objects += src + +/obj/item/device/camera_bug/Destroy() + if(expansion) + qdel(expansion) + expansion = null + del(src) +/* Easier to just call del() than this nonsense + get_cameras() + for(var/cam_tag in bugged_cameras) + var/obj/machinery/camera/camera = bugged_cameras[cam_tag] + if(camera.bug == src) + camera.bug = null + bugged_cameras = list() + if(tracking) + tracking = null + ..() +*/ + +/obj/item/device/camera_bug/interact(var/mob/user = usr) + var/datum/browser/popup = new(user, "camerabug","Camera Bug",nref=src) + popup.set_content(menu(get_cameras())) + popup.open() + +/obj/item/device/camera_bug/attack_self(mob/user as mob) + user.set_machine(src) + interact(user) + +/obj/item/device/camera_bug/check_eye(var/mob/user as mob) + if (user.stat || loc != user || !user.canmove || user.eye_blind || !current) + user.reset_view(null) + user.unset_machine() + return null + + var/turf/T = get_turf(user.loc) + if(T.z != current.z || (!skip_bugcheck && current.bug != src) || !current.can_use()) + user << "[src] has lost the signal." + current = null + user.reset_view(null) + user.unset_machine() + return null + + return 1 + +/obj/item/device/camera_bug/proc/get_cameras() + if(bugtype != last_bugtype || ( (bugtype in list(UNIVERSAL_BUG,NETWORK_BUG,ADMIN_BUG)) && world.time > (last_net_update + 100))) + bugged_cameras = list() + last_bugtype = bugtype + for(var/obj/machinery/camera/camera in cameranet.cameras) + if(camera.stat || !camera.can_use()) + continue + switch(bugtype) + if(VANILLA_BUG,SABOTAGE_BUG,ADVANCED_BUG) + if(camera.bug == src) + bugged_cameras[camera.c_tag] = camera + if(UNIVERSAL_BUG) + if(camera.bug) + bugged_cameras[camera.c_tag] = camera + if(NETWORK_BUG,ADMIN_BUG) + if(length(list("SS13","MINE")&camera.network)) + bugged_cameras[camera.c_tag] = camera + sortList(bugged_cameras) + return bugged_cameras + + +/obj/item/device/camera_bug/proc/menu(var/list/cameras) + if(!cameras || !cameras.len) + return "No bugged cameras found." + + var/html + switch(track_mode) + if(BUGMODE_LIST) + html = "

    Select a camera:

    \[Cancel camera view\]
    " + for(var/entry in cameras) + var/obj/machinery/camera/C = cameras[entry] + var/functions = "" + switch(bugtype) + if(SABOTAGE_BUG) + functions = " - \[Disable\]" + if(ADVANCED_BUG) + functions = " - \[Monitor\]" + if(ADMIN_BUG) + if(C.bug == src) + functions = " - \[Monitor\]\[Disable\]" + else + functions = " - \[Monitor\]" + html += "" + + if(BUGMODE_MONITOR) + if(current) + html = "Analyzing Camera '[current.c_tag]' \[Select Camera\]
    " + html += camera_report() + else + track_mode = BUGMODE_LIST + return .(cameras) + if(BUGMODE_TRACK) + if(tracking) + html = "Tracking '[tracked_name]' \[Cancel Tracking\]\[Cancel camera view\]
    " + if(last_found) + var/time_diff = round((world.time - last_seen) / 150) + var/obj/machinery/camera/C = bugged_cameras[last_found] + var/outstring + if(C) + outstring = "[last_found]" + else + outstring = last_found + if(!time_diff) + html += "Last seen near [outstring] (now)
    " + else + // 15 second intervals ~ 1/4 minute + var/m = round(time_diff/4) + var/s = (time_diff - 4*m) * 15 + if(!s) s = "00" + html += "Last seen near [outstring] ([m]:[s] minute\s ago)
    " + else + html += "Not yet seen." + else + track_mode = BUGMODE_LIST + return .(cameras) + return html + +/obj/item/device/camera_bug/proc/camera_report() + // this should only be called if current exists + var/dat = "" + if(current && current.can_use()) + var/list/seen = current.can_see() + var/list/names = list() + for(var/obj/machinery/singularity/S in seen) // god help you if you see more than one + if(S.name in names) + names[S.name]++ + dat += "[S.name] ([names[S.name]])" + else + names[S.name] = 1 + dat += "[S.name]" + var/stage = round(S.current_size / 2)+1 + dat += " (Stage [stage])" + dat += " \[Track\]
    " + + for(var/obj/mecha/M in seen) + if(M.name in names) + names[M.name]++ + dat += "[M.name] ([names[M.name]])" + else + names[M.name] = 1 + dat += "[M.name]" + dat += " \[Track\]
    " + + + for(var/mob/living/M in seen) + if(M.name in names) + names[M.name]++ + dat += "[M.name] ([names[M.name]])" + else + names[M.name] = 1 + dat += "[M.name]" + if(M.buckled && !M.lying) + dat += " (Sitting)" + if(M.lying) + dat += " (Laying down)" + dat += " \[Track\]
    " + if(length(dat) == 0) + dat += "No motion detected." + return dat + else + return "Camera Offline
    " + +/obj/item/device/camera_bug/Topic(var/href,var/list/href_list) + if(usr != loc) + usr.unset_machine() + usr.reset_view(null) + usr << browse(null, "window=camerabug") + return + usr.set_machine(src) + if("mode" in href_list) + track_mode = text2num(href_list["mode"]) + if("monitor" in href_list) + var/obj/machinery/camera/C = locate(href_list["monitor"]) + if(C) + track_mode = BUGMODE_MONITOR + current = C + usr.reset_view(null) + interact() + if("track" in href_list) + var/atom/A = locate(href_list["track"]) + if(A) + tracking = A + tracked_name = A.name + last_found = current.c_tag + last_seen = world.time + track_mode = BUGMODE_TRACK + if("emp" in href_list) + var/obj/machinery/camera/C = locate(href_list["emp"]) + if(istype(C) && C.bug == src) + C.emp_act(1) + C.bug = null + bugged_cameras -= C.c_tag + interact() + return + if("close" in href_list) + usr.reset_view(null) + usr.unset_machine() + current = null + return // I do not <- I do not remember what I was going to write in this comment -Sayu, sometime later + if("view" in href_list) + var/obj/machinery/camera/C = locate(href_list["view"]) + if(istype(C)) + if(!C.can_use()) + usr << "Something's wrong with that camera. You can't get a feed." + return + var/turf/T = get_turf(loc) + if(!T || C.z != T.z) + usr << "You can't get a signal." + return + current = C + spawn(6) + if(src.check_eye(usr)) + usr.reset_view(C) + interact() + else + usr.unset_machine() + usr.reset_view(null) + usr << browse(null, "window=camerabug") + return + else + usr.unset_machine() + usr.reset_view(null) + + interact() + +/obj/item/device/camera_bug/process() + if(track_mode == BUGMODE_LIST || (world.time < (last_tracked + refresh_interval))) + return + last_tracked = world.time + if(track_mode == BUGMODE_TRACK ) // search for user + // Note that it will be tricked if your name appears to change. + // This is not optimal but it is better than tracking you relentlessly despite everything. + if(!tracking) + src.updateSelfDialog() + return + + if(tracking.name != tracked_name) // Hiding their identity, tricksy + var/mob/M = tracking + if(istype(M)) + if(!(tracked_name == "Unknown" && findtext(tracking.name,"Unknown"))) // we saw then disguised before + if(!(tracked_name == M.real_name && findtext(tracking.name,M.real_name))) // or they're still ID'd + src.updateSelfDialog()//But if it's neither of those cases + return // you won't find em on the cameras + else + src.updateSelfDialog() + return + + var/list/tracking_cams = list() + var/list/b_cams = get_cameras() + for(var/entry in b_cams) + tracking_cams += b_cams[entry] + var/list/target_region = view(tracking) + + for(var/obj/machinery/camera/C in (target_region & tracking_cams)) + if(!can_see(C,tracking)) // target may have xray, that doesn't make them visible to cameras + continue + if(C.can_use()) + last_found = C.c_tag + last_seen = world.time + break + src.updateSelfDialog() + +/obj/item/device/camera_bug/attackby(var/obj/item/W as obj,var/mob/living/user as mob, params) + if(istype(W,/obj/item/weapon/screwdriver) && expansion) + expansion.loc = get_turf(loc) + user << "You unscrew [expansion]." + user.put_in_inactive_hand(expansion) + expansion = null + bugtype = VANILLA_BUG + skip_bugcheck = 0 + track_mode = BUGMODE_LIST + tracking = null + return + + if(expansion || !W) + return ..(W,user) + + // I am not sure that this list is or should be final + // really I do not know what to do here. + var/static/list/expandables = list( + /obj/item/weapon/research = ADMIN_BUG, // could have been anything spawn-only + + // these are all so hackish I am sorry + + /obj/item/device/analyzer = UNIVERSAL_BUG, + /obj/item/weapon/stock_parts/subspace/analyzer = UNIVERSAL_BUG, + + /obj/item/device/assembly/igniter = SABOTAGE_BUG, + /obj/item/device/assembly/infra = SABOTAGE_BUG, // ir blaster to disable camera + /obj/item/weapon/stock_parts/subspace/amplifier = SABOTAGE_BUG, + + /obj/item/device/radio = NETWORK_BUG, + /obj/item/device/assembly/signaler = NETWORK_BUG, + /obj/item/weapon/stock_parts/subspace/transmitter = NETWORK_BUG, + + /obj/item/device/detective_scanner = ADVANCED_BUG, + /obj/item/device/paicard = ADVANCED_BUG, + /obj/item/weapon/stock_parts/scanning_module = ADVANCED_BUG + ) + + for(var/entry in expandables) + if(istype(W,entry)) + bugtype = expandables[entry] + user.drop_item() + W.loc = src + expansion = W + user << "You add [W] to [src]." + get_cameras() // the tracking code will want to know the new camera list + if(bugtype in list(UNIVERSAL_BUG,NETWORK_BUG,ADMIN_BUG)) + skip_bugcheck = 1 + return + +#undef VANILLA_BUG +#undef UNIVERSAL_BUG +#undef NETWORK_BUG +#undef SABOTAGE_BUG +#undef ADVANCED_BUG +#undef ADMIN_BUG + +#undef BUGMODE_LIST +#undef BUGMODE_MONITOR +#undef BUGMODE_TRACK \ No newline at end of file diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm index 008a469dff9..de79a855768 100644 --- a/code/game/objects/items/devices/chameleonproj.dm +++ b/code/game/objects/items/devices/chameleonproj.dm @@ -1,7 +1,7 @@ /obj/item/device/chameleon name = "chameleon-projector" icon_state = "shield0" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT item_state = "electronic" throwforce = 5.0 diff --git a/code/game/objects/items/devices/debugger.dm b/code/game/objects/items/devices/debugger.dm index 7a05fc696a9..1b9d5e13344 100644 --- a/code/game/objects/items/devices/debugger.dm +++ b/code/game/objects/items/devices/debugger.dm @@ -9,7 +9,7 @@ name = "debugger" desc = "Used to debug electronic equipment." icon_state = "hacktool-g" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT force = 5.0 w_class = 2.0 throwforce = 5.0 diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm index 9c17c585b39..8643a20aaa5 100644 --- a/code/game/objects/items/devices/flash.dm +++ b/code/game/objects/items/devices/flash.dm @@ -7,7 +7,7 @@ w_class = 1 throw_speed = 3 throw_range = 7 - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT origin_tech = "magnets=2;combat=1" var/times_used = 0 //Number of times it's been used. @@ -16,7 +16,7 @@ /obj/item/device/flash/proc/clown_check(mob/user) - if(user && (M_CLUMSY in user.mutations) && prob(50)) + if(user && (CLUMSY in user.mutations) && prob(50)) flash_carbon(user, user, 15, 0) return 0 return 1 @@ -66,10 +66,11 @@ if(user && convert) terrible_conversion_proc(M, user) M.Stun(1) - user.visible_message("[user] blinds [M] with the flash!") + user.visible_message("[user] blinds [M] with the flash!") return 1 else - user.visible_message("[user] fails to blind [M] with the flash!") + if(user) + user.visible_message("[user] fails to blind [M] with the flash!") return 0 /obj/item/device/flash/attack(mob/living/M, mob/user) diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 5c4201e2bc0..05a851b0d28 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -5,7 +5,7 @@ icon_state = "flashlight" item_state = "flashlight" w_class = 2 - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT m_amt = 50 g_amt = 20 @@ -49,7 +49,7 @@ add_fingerprint(user) if(on && user.zone_sel.selecting == "eyes") - if(((M_CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50)) //too dumb to use flashlight properly + if(((CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50)) //too dumb to use flashlight properly return ..() //just hit them in the head if(!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") //don't have dexterity @@ -77,7 +77,7 @@ if(istype(M, /mob/living/carbon/human) || istype(M, /mob/living/carbon/monkey)) //robots and aliens are unaffected if(M.stat == DEAD || M.sdisabilities & BLIND) //mob is dead or fully blind user << "[M] pupils does not react to the light!" - else if(M_XRAY in M.mutations) //mob has X-RAY vision + else if(XRAY in M.mutations) //mob has X-RAY vision flick("flash", M.flash) //Yes, you can still get flashed wit X-Ray. user << "[M] pupils give an eerie glow!" else //they're okay! @@ -107,7 +107,7 @@ item_state = "" w_class = 1 slot_flags = SLOT_BELT | SLOT_EARS - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT brightness_on = 2 /obj/item/device/flashlight/seclite @@ -125,7 +125,7 @@ desc = "A miniature lamp, that might be used by small robots." icon_state = "penlight" item_state = "" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT brightness_on = 2 w_class = 1 diff --git a/code/game/objects/items/devices/handtv.dm b/code/game/objects/items/devices/handtv.dm deleted file mode 100644 index 0406db85852..00000000000 --- a/code/game/objects/items/devices/handtv.dm +++ /dev/null @@ -1,47 +0,0 @@ -/obj/item/device/handtv - name = "handheld tv" - desc = "A handheld tv meant for remote viewing." - icon_state = "handtv" - w_class = 1 - var/obj/machinery/camera/current = null - -/obj/item/device/handtv/attack_self(mob/usr as mob) - var/list/cameras = new/list() - for (var/obj/machinery/camera/C in cameranet.viewpoints) - if (C.hasbug && C.status) - cameras.Add(C) - if (length(cameras) == 0) - usr << "\red No bugged functioning cameras found." - return - - var/list/friendly_cameras = new/list() - - for (var/obj/machinery/camera/C in cameras) - friendly_cameras.Add(C.c_tag) - - var/target = input("Select the camera to observe", null) as null|anything in friendly_cameras - if (!target) - usr.unset_machine() - usr.reset_view(usr) - src.in_use = 0 - return - for (var/obj/machinery/camera/C in cameras) - if (C.c_tag == target) - target = C - break - if (usr.stat == 2) return - if(target) - usr.client.eye = target - usr.set_machine(src) - src.current = target - src.in_use = 1 - else - usr.unset_machine() - src.in_use = 0 - return - -/obj/item/device/handtv/check_eye(var/mob/usr as mob) - if ( src.loc != usr || usr.get_active_hand() != src|| !usr.canmove || usr.blinded || !current || !current.status ) - return null - usr.reset_view(current) - return 1 \ No newline at end of file diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm index 9c8f766714f..5c104fcef54 100644 --- a/code/game/objects/items/devices/laserpointer.dm +++ b/code/game/objects/items/devices/laserpointer.dm @@ -5,7 +5,7 @@ icon_state = "pointer" item_state = "pen" var/pointer_icon_state - flags = FPRINT | TABLEPASS | CONDUCT | USEDELAY + flags = CONDUCT slot_flags = SLOT_BELT m_amt = 500 g_amt = 500 @@ -45,7 +45,7 @@ /obj/item/device/laser_pointer/attack(mob/living/M, mob/user) laser_act(M, user) -/obj/item/device/laser_pointer/attackby(obj/item/W, mob/user) +/obj/item/device/laser_pointer/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/weapon/stock_parts/micro_laser)) if(!diode) user.drop_item() diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index 63836e9ecc6..3d9e623d53b 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -47,7 +47,7 @@ icon_state = "lightreplacer0" item_state = "electronic" - flags = FPRINT | CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT origin_tech = "magnets=3;materials=2" @@ -71,11 +71,7 @@ ..() usr << "It has [uses] lights remaining." -/obj/item/device/lightreplacer/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/weapon/card/emag) && emagged == 0) - Emag() - return - +/obj/item/device/lightreplacer/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/stack/sheet/glass)) var/obj/item/stack/sheet/glass/G = W if(G.amount - decrement >= 0 && uses < max_uses) @@ -104,7 +100,10 @@ user << "You need a working light." return - +/obj/item/device/lightreplacer/emag_act(user as mob) + if(!emagged) + Emag() + /obj/item/device/lightreplacer/attack_self(mob/user) /* // This would probably be a bit OP. If you want it though, uncomment the code. if(isrobot(user)) diff --git a/code/game/objects/items/devices/megaphone.dm b/code/game/objects/items/devices/megaphone.dm index 0d12f8262b6..11f706f01ba 100644 --- a/code/game/objects/items/devices/megaphone.dm +++ b/code/game/objects/items/devices/megaphone.dm @@ -4,7 +4,7 @@ icon_state = "megaphone" item_state = "radio" w_class = 1.0 - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT var/spamcheck = 0 var/emagged = 0 @@ -26,7 +26,7 @@ user << "\red \The [src] needs to recharge!" return - var/message = copytext(sanitize(input(user, "Shout a message?", "Megaphone", null) as text),1,MAX_MESSAGE_LEN) + var/message = sanitize(copytext(input(user, "Shout a message?", "Megaphone", null) as text,1,MAX_MESSAGE_LEN)) if(!message) return message = capitalize(message) @@ -47,10 +47,8 @@ spamcheck = 0 return -/obj/item/device/megaphone/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/weapon/card/emag) && !emagged) +/obj/item/device/megaphone/emag_act(user as mob) + if(!emagged) user << "\red You overload \the [src]'s voice synthesizer." emagged = 1 insults = rand(1, 3)//to prevent dickflooding - return - return \ No newline at end of file diff --git a/code/game/objects/items/devices/modkit.dm b/code/game/objects/items/devices/modkit.dm index 6e23e94d4ad..61c83fdc462 100644 --- a/code/game/objects/items/devices/modkit.dm +++ b/code/game/objects/items/devices/modkit.dm @@ -23,7 +23,7 @@ if(!parts) user << "This kit has no parts for this modification left." - user.drop_from_inventory(src) + user.unEquip(src) del(src) return @@ -59,7 +59,7 @@ parts &= ~MODKIT_SUIT if(!parts) - user.drop_from_inventory(src) + user.unEquip(src) del(src) /obj/item/device/modkit/examine() diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm index 85a30681b1a..21bd2c49ddf 100644 --- a/code/game/objects/items/devices/multitool.dm +++ b/code/game/objects/items/devices/multitool.dm @@ -8,7 +8,7 @@ name = "multitool" desc = "Used for pulsing wires to test which to cut. Not recommended by doctors." icon_state = "multitool" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT force = 5.0 w_class = 2.0 throwforce = 5.0 diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm index cb7dea3371d..b5d14aa8982 100644 --- a/code/game/objects/items/devices/paicard.dm +++ b/code/game/objects/items/devices/paicard.dm @@ -4,7 +4,6 @@ icon_state = "pai" item_state = "electronic" w_class = 2.0 - flags = FPRINT | TABLEPASS slot_flags = SLOT_BELT origin_tech = "programming=2" var/obj/item/device/radio/radio @@ -162,19 +161,13 @@
    [entry][functions]
    - - - - - - @@ -266,10 +259,13 @@ removePersonality() if(href_list["wires"]) var/t1 = text2num(href_list["wires"]) - if(radio) - radio.wires.CutWireIndex(t1) + switch(t1) + if(4) + radio.ToggleBroadcast() + if(2) + radio.ToggleReception() if(href_list["setlaws"]) - var/newlaws = copytext(sanitize(input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.pai_laws) as message),1,MAX_MESSAGE_LEN) + var/newlaws = sanitize(copytext(input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.pai_laws) as message,1,MAX_MESSAGE_LEN)) if(newlaws) pai.pai_laws = newlaws pai << "Your supplemental directives have been updated. Your new directives are:" diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index 088a51574ab..f9907855224 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -6,7 +6,7 @@ icon_state = "powersink0" item_state = "electronic" w_class = 4.0 - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT throwforce = 5 throw_speed = 1 throw_range = 2 @@ -21,7 +21,7 @@ var/obj/structure/cable/attached // the attached cable - attackby(var/obj/item/I, var/mob/user) + attackby(var/obj/item/I, var/mob/user, params) if(istype(I, /obj/item/weapon/screwdriver)) if(mode == 0) var/turf/T = loc diff --git a/code/game/objects/items/devices/radio/beacon.dm b/code/game/objects/items/devices/radio/beacon.dm index 15f59e66dcb..628a6ee8bba 100644 --- a/code/game/objects/items/devices/radio/beacon.dm +++ b/code/game/objects/items/devices/radio/beacon.dm @@ -8,15 +8,11 @@ var/emagged = 0 var/syndicate = 0 -/obj/item/device/radio/beacon/attackby(I as obj, mob/living/user as mob) - if(istype(I,/obj/item/weapon/card/emag)) // If hit by an emag. - var/obj/item/weapon/card/emag/E = I - if(!emagged) - if(E.uses) - E.uses-- - emagged = 1 - syndicate = 1 - user << "\blue The This beacon now only be locked on to by emagged teleporters!" +/obj/item/device/radio/beacon/emag_act(user as mob) + if(!emagged) + emagged = 1 + syndicate = 1 + user << "\blue The This beacon now only be locked on to by emagged teleporters!" /obj/item/device/radio/beacon/hear_talk() return diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index ccdc3a9bce4..ff5c90e0985 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -4,7 +4,7 @@ icon_state = "electropack0" item_state = "electropack" frequency = 1449 - flags = FPRINT | CONDUCT | TABLEPASS + flags = CONDUCT slot_flags = SLOT_BACK w_class = 5.0 g_amt = 2500 @@ -26,7 +26,7 @@ S.part2 = null master = null -/obj/item/device/radio/electropack/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/device/radio/electropack/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if(istype(W, /obj/item/clothing/head/helmet)) if(!b_stat) @@ -35,18 +35,22 @@ var/obj/item/assembly/shock_kit/A = new /obj/item/assembly/shock_kit( user ) A.icon = 'icons/obj/assemblies.dmi' - user.drop_from_inventory(W) + if(!user.unEquip(W)) + user << "\the [W] is stuck to your hand, you cannot attach it to \the [src]!" + return W.loc = A W.master = A A.part1 = W - user.drop_from_inventory(src) + user.unEquip(src) loc = A master = A A.part2 = src user.put_in_hands(A) A.add_fingerprint(user) + if(src.flags & NODROP) + A.flags |= NODROP /obj/item/device/radio/electropack/Topic(href, href_list) //..() diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm index bd4119ecef3..2c112dc12d0 100644 --- a/code/game/objects/items/devices/radio/encryptionkey.dm +++ b/code/game/objects/items/devices/radio/encryptionkey.dm @@ -13,7 +13,7 @@ /obj/item/device/encryptionkey/New() -/obj/item/device/encryptionkey/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/device/encryptionkey/attackby(obj/item/weapon/W as obj, mob/user as mob, params) /obj/item/device/encryptionkey/syndicate icon_state = "cypherkey" diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index 32bf7da3c7a..674cb41517f 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -1,9 +1,9 @@ /obj/item/device/radio/headset name = "radio headset" desc = "An updated, modular intercom that fits over the head. Takes encryption keys." + var/radio_desc = "" icon_state = "headset" item_state = "headset" - g_amt = 0 m_amt = 75 subspace_transmission = 1 canhear_range = 0 // can't hear headsets from very far away @@ -15,20 +15,45 @@ var/obj/item/device/encryptionkey/keyslot2 = null maxf = 1489 + var/ks1type = null + var/ks2type = null + /obj/item/device/radio/headset/New() ..() - recalculateChannels() + if(ks1type) + keyslot1 = new ks1type(src) + if(ks2type) + keyslot2 = new ks2type(src) + recalculateChannels(1) +/obj/item/device/radio/headset/examine(mob/user) + if(!(..(user, 1) && radio_desc)) + return + + user << "The following channels are built-in:" + user << radio_desc + +/obj/item/device/radio/headset/handle_message_mode(mob/living/M as mob, message, channel) + if (channel == "special") + if (translate_binary) + var/datum/language/binary = all_languages["Robot Talk"] + binary.broadcast(M, message) + if (translate_hive) + var/datum/language/hivemind = all_languages["Hivemind"] + hivemind.broadcast(M, message) + return null + + return ..() /obj/item/device/radio/headset/receive_range(freq, level, aiOverride = 0) - if(aiOverride) + if (aiOverride) return ..(freq, level) if(ishuman(src.loc)) var/mob/living/carbon/human/H = src.loc if(H.l_ear == src || H.r_ear == src) return ..(freq, level) return -1 - + /obj/item/device/radio/headset/alt name = "bowman headset" desc = "An updated, modular intercom that fits over the head. Takes encryption keys. Protects ears from flashbangs." @@ -38,219 +63,216 @@ /obj/item/device/radio/headset/syndicate origin_tech = "syndicate=3" + syndie = 1 + ks1type = /obj/item/device/encryptionkey/syndicate /obj/item/device/radio/headset/syndicate/alt //undisguised bowman with flash protection name = "syndicate headset" - desc = "A syndicate headset that can be used to hear all radio frequencies. Protects ears from flashbangs. \nTo access the syndicate channel, use ; before speaking." + desc = "A syndicate headset that can be used to hear all radio frequencies. Protects ears from flashbangs." flags = EARBANGPROTECT origin_tech = "syndicate=3" icon_state = "syndie_headset" item_state = "syndie_headset" -/obj/item/device/radio/headset/syndicate/New() - ..() - del(keyslot1) - keyslot1 = new /obj/item/device/encryptionkey/syndicate - syndie = 1 - recalculateChannels() - /obj/item/device/radio/headset/binary origin_tech = "syndicate=3" -/obj/item/device/radio/headset/binary/New() - ..() - del(keyslot1) - keyslot1 = new /obj/item/device/encryptionkey/binary - recalculateChannels() + ks1type = /obj/item/device/encryptionkey/binary /obj/item/device/radio/headset/headset_sec name = "security radio headset" - desc = "This is used by your elite security force. To access the security channel, use :s." + desc = "This is used by your elite security force." icon_state = "sec_headset" item_state = "headset" - keyslot1 = new /obj/item/device/encryptionkey/headset_sec + ks2type = /obj/item/device/encryptionkey/headset_sec /obj/item/device/radio/headset/headset_sec/alt name = "security bowman headset" - desc = "This is used by your elite security force. Protects ears from flashbangs. \nTo access the security channel, use :s." + desc = "This is used by your elite security force. Protects ears from flashbangs." flags = EARBANGPROTECT icon_state = "sec_headset_alt" item_state = "sec_headset_alt" /obj/item/device/radio/headset/headset_eng name = "engineering radio headset" - desc = "When the engineers wish to chat like girls. To access the engineering channel, use :e. " + desc = "When the engineers wish to chat like girls." icon_state = "eng_headset" item_state = "headset" - keyslot1 = new /obj/item/device/encryptionkey/headset_eng + ks2type = /obj/item/device/encryptionkey/headset_eng /obj/item/device/radio/headset/headset_rob name = "robotics radio headset" - desc = "Made specifically for the roboticists who cannot decide between departments. To access the engineering channel, use :e. For research, use :n." + desc = "Made specifically for the roboticists who cannot decide between departments." icon_state = "rob_headset" item_state = "headset" - keyslot1 = new /obj/item/device/encryptionkey/headset_rob + ks2type = /obj/item/device/encryptionkey/headset_rob /obj/item/device/radio/headset/headset_med name = "medical radio headset" - desc = "A headset for the trained staff of the medbay. To access the medical channel, use :m." + desc = "A headset for the trained staff of the medbay." icon_state = "med_headset" item_state = "headset" - keyslot1 = new /obj/item/device/encryptionkey/headset_med + ks2type = /obj/item/device/encryptionkey/headset_med /obj/item/device/radio/headset/headset_sci name = "science radio headset" - desc = "A sciency headset. Like usual. To access the science channel, use :n." + desc = "A sciency headset. Like usual." icon_state = "sci_headset" item_state = "headset" - keyslot1 = new /obj/item/device/encryptionkey/headset_sci + ks2type = /obj/item/device/encryptionkey/headset_sci /obj/item/device/radio/headset/headset_medsci name = "medical research radio headset" - desc = "A headset that is a result of the mating between medical and science. To access the medical channel, use :m. For science, use :n." + desc = "A headset that is a result of the mating between medical and science." icon_state = "medsci_headset" item_state = "headset" - keyslot1 = new /obj/item/device/encryptionkey/headset_medsci + ks2type = /obj/item/device/encryptionkey/headset_medsci /obj/item/device/radio/headset/headset_com name = "command radio headset" - desc = "A headset with a commanding channel. To access the command channel, use :c." + desc = "A headset with a commanding channel." icon_state = "com_headset" item_state = "headset" - keyslot1 = new /obj/item/device/encryptionkey/headset_com + ks2type = /obj/item/device/encryptionkey/headset_com /obj/item/device/radio/headset/heads/captain name = "captain's headset" - desc = "The headset of the boss. Channels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :z - service, :m - medical, :n - science." + desc = "The headset of the boss." icon_state = "com_headset" item_state = "headset" - keyslot1 = new /obj/item/device/encryptionkey/heads/captain + ks2type = /obj/item/device/encryptionkey/heads/captain /obj/item/device/radio/headset/heads/captain/alt name = "\proper the captain's bowman headset" - desc = "The headset of the boss. Protects ears from flashbangs. \nChannels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :v - service, :m - medical, :n - science." + desc = "The headset of the boss. Protects ears from flashbangs." flags = EARBANGPROTECT icon_state = "com_headset_alt" item_state = "com_headset_alt" /obj/item/device/radio/headset/heads/rd name = "Research Director's headset" - desc = "Headset of the researching God. To access the science channel, use :n. For command, use :c." + desc = "Headset of the researching God." icon_state = "com_headset" item_state = "headset" - keyslot1 = new /obj/item/device/encryptionkey/heads/rd + ks2type = /obj/item/device/encryptionkey/heads/rd /obj/item/device/radio/headset/heads/hos name = "head of security's headset" - desc = "The headset of the man who protects your worthless lifes. To access the security channel, use :s. For command, use :c." + desc = "The headset of the man who protects your worthless lives." icon_state = "com_headset" item_state = "headset" - keyslot1 = new /obj/item/device/encryptionkey/heads/hos + ks2type = /obj/item/device/encryptionkey/heads/hos /obj/item/device/radio/headset/heads/hos/alt name = "\proper the head of security's bowman headset" - desc = "The headset of the man in charge of keeping order and protecting the station. Protects ears from flashbangs. \nTo access the security channel, use :s. For command, use :c." + desc = "The headset of the man in charge of keeping order and protecting the station. Protects ears from flashbangs." flags = EARBANGPROTECT icon_state = "com_headset_alt" item_state = "com_headset_alt" /obj/item/device/radio/headset/heads/ce name = "chief engineer's headset" - desc = "The headset of the guy who is in charge of morons. To access the engineering channel, use :e. For command, use :c." + desc = "The headset of the guy who is in charge of morons." icon_state = "com_headset" item_state = "headset" - keyslot1 = new /obj/item/device/encryptionkey/heads/ce + ks2type = /obj/item/device/encryptionkey/heads/ce /obj/item/device/radio/headset/heads/cmo name = "chief medical officer's headset" - desc = "The headset of the highly trained medical chief. To access the medical channel, use :m. For command, use :c." + desc = "The headset of the highly trained medical chief." icon_state = "com_headset" item_state = "headset" - keyslot1 = new /obj/item/device/encryptionkey/heads/cmo + ks2type = /obj/item/device/encryptionkey/heads/cmo /obj/item/device/radio/headset/heads/hop name = "head of personnel's headset" - desc = "The headset of the guy who will one day be captain. Channels are as follows: :u - supply, :z - service, :s - security, :c - command." + desc = "The headset of the guy who will one day be captain." icon_state = "com_headset" item_state = "headset" - keyslot1 = new /obj/item/device/encryptionkey/heads/hop + ks2type = /obj/item/device/encryptionkey/heads/hop /* /obj/item/device/radio/headset/headset_mine name = "mining radio headset" - desc = "Headset used by miners. How useless. To access the mining channel, use :d." + desc = "Headset used by miners. How useless." icon_state = "mine_headset" item_state = "headset" - keyslot1 = new /obj/item/device/encryptionkey/headset_mine + ks2type = /obj/item/device/encryptionkey/headset_mine /obj/item/device/radio/headset/heads/qm name = "quartermaster's headset" - desc = "The headset of the man who control your toiletpaper supply. To access the cargo channel, use :q. For mining, use :d." + desc = "The headset of the man who control your toiletpaper supply." icon_state = "cargo_headset" item_state = "headset" - keyslot1 = new /obj/item/device/encryptionkey/heads/qm + ks2type = /obj/item/device/encryptionkey/heads/qm */ /obj/item/device/radio/headset/headset_cargo name = "supply radio headset" - desc = "A headset used by the cargo department. To access the supply channel, use :u." + desc = "A headset used by the cargo department." icon_state = "cargo_headset" item_state = "headset" - keyslot1 = new /obj/item/device/encryptionkey/headset_cargo + ks2type = /obj/item/device/encryptionkey/headset_cargo /obj/item/device/radio/headset/headset_service name = "service radio headset" - desc = "Headset used by the service staff, tasked with keeping the station full, happy and clean. To access the service channel, use :z." + desc = "Headset used by the service staff, tasked with keeping the station full, happy and clean." icon_state = "srv_headset" item_state = "headset" - keyslot1 = new /obj/item/device/encryptionkey/headset_service + ks2type = /obj/item/device/encryptionkey/headset_service /obj/item/device/radio/headset/heads/ntrep name = "nanotrasen representative's headset" - desc = "The headset of the Nanotrasen Representative. Channels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :z - service, :m - medical, :n - science." + desc = "The headset of the Nanotrasen Representative." icon_state = "com_headset" item_state = "headset" - keyslot1 = new /obj/item/device/encryptionkey/heads/ntrep + ks2type = /obj/item/device/encryptionkey/heads/ntrep /obj/item/device/radio/headset/heads/magistrate name = "magistrate's headset" - desc = "The headset of the Magistrate. Channels are as follows: :c - command, :s - security." + desc = "The headset of the Magistrate." icon_state = "com_headset" item_state = "headset" - keyslot1 = new /obj/item/device/encryptionkey/heads/magistrate + ks2type = /obj/item/device/encryptionkey/heads/magistrate /obj/item/device/radio/headset/heads/blueshield name = "blueshield's headset" - desc = "The headset of the Blueshield. Channels are as follows: :c - command, :s - security." + desc = "The headset of the Blueshield." icon_state = "com_headset" item_state = "headset" - keyslot1 = new /obj/item/device/encryptionkey/heads/blueshield + ks2type = /obj/item/device/encryptionkey/heads/blueshield -/obj/item/device/radio/headset/ert - name = "emergency response team headset" - desc = "The headset of the boss's boss. Channels are as follows: :h - Response Team :c - command, :s - security, :e - engineering, :d - mining, :u - cargo, :z - service, :m - medical, :n - science." - icon_state = "com_headset" - item_state = "headset" - freerange = 1 - keyslot1 = new /obj/item/device/encryptionkey/ert - -/obj/item/device/radio/headset/ert/alt - name = "\proper emergency response team's bowman headset" - desc = "The headset of the boss. Protects ears from flashbangs. \nChannels are as follows: :h - Response Team, :c - command, :s - security, :e - engineering, :u - supply, :v - service, :m - medical, :n - science." +/obj/item/device/radio/headset/heads/blueshield/alt + name = "\proper blueshield's bowman headset" + desc = "The headset of the Blueshield. Protects ears from flashbangs." + flags = EARBANGPROTECT + icon_state = "com_headset_alt" + item_state = "com_headset_alt" + +/obj/item/device/radio/headset/ert + name = "emergency response team headset" + desc = "The headset of the boss's boss." + icon_state = "com_headset" + item_state = "headset" + freerange = 1 + ks2type = /obj/item/device/encryptionkey/ert + +/obj/item/device/radio/headset/ert/alt + name = "\proper emergency response team's bowman headset" + desc = "The headset of the boss. Protects ears from flashbangs." flags = EARBANGPROTECT icon_state = "com_headset_alt" item_state = "com_headset_alt" -//The below was ported from Baystation. /obj/item/device/radio/headset/heads/ai_integrated //No need to care about icons, it should be hidden inside the AI anyway. - name = "AI Subspace Transceiver" + name = "\improper AI subspace transceiver" desc = "Integrated AI radio transceiver." icon = 'icons/obj/robot_component.dmi' icon_state = "radio" item_state = "headset" - keyslot2 = new /obj/item/device/encryptionkey/heads/ai_integrated - var/myAi = null // Atlantis: Reference back to the AI which has this radio. + ks2type = /obj/item/device/encryptionkey/heads/ai_integrated + var/myAi = null // Atlantis: Reference back to the AI which has this radio. var/disabledAi = 0 // Atlantis: Used to manually disable AI's integrated radio via intellicard menu. /obj/item/device/radio/headset/heads/ai_integrated/receive_range(freq, level) - if(disabledAi) + if (disabledAi) return -1 //Transciever Disabled. return ..(freq, level, 1) @@ -287,7 +309,7 @@ user << "You pop out the encryption keys in the headset!" else - user << "This headset doesn't have any unique encryption keys! How useless..." + user << "This headset doesn't have any encryption keys! How useless..." if(istype(W, /obj/item/device/encryptionkey/)) if(keyslot1 && keyslot2) @@ -310,7 +332,7 @@ return -/obj/item/device/radio/headset/proc/recalculateChannels() +/obj/item/device/radio/headset/proc/recalculateChannels(var/setDescription = 0) src.channels = list() src.translate_binary = 0 src.translate_hive = 0 @@ -358,4 +380,18 @@ secure_radio_connections[ch_name] = radio_controller.add_object(src, radiochannels[ch_name], RADIO_CHAT) + if(setDescription) + setupRadioDescription() + return + +/obj/item/device/radio/headset/proc/setupRadioDescription() + var/radio_text = "" + for(var/i = 1 to channels.len) + var/channel = channels[i] + var/key = get_radio_key_from_channel(channel) + radio_text += "[key] - [channel]" + if(i != channels.len) + radio_text += ", " + + radio_desc = radio_text diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index 3f30f0c03e7..567dc49bf4f 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -4,8 +4,8 @@ icon_state = "intercom" anchored = 1 w_class = 4.0 - canhear_range = 5 - flags = FPRINT | CONDUCT | TABLEPASS | NOBLOODY + canhear_range = 2 + flags = CONDUCT | NOBLOODY var/number = 0 var/anyai = 1 var/mob/living/silicon/ai/ai = list() @@ -15,7 +15,7 @@ ..() processing_objects += src -/obj/item/device/radio/intercom/Destroy() +/obj/item/device/radio/intercom/Del() processing_objects -= src ..() @@ -24,10 +24,6 @@ spawn (0) attack_self(user) -/obj/item/device/radio/intercom/attack_paw(mob/user as mob) - return src.attack_hand(user) - - /obj/item/device/radio/intercom/attack_hand(mob/user as mob) src.add_fingerprint(user) spawn (0) @@ -36,15 +32,13 @@ /obj/item/device/radio/intercom/receive_range(freq, level) if (!on) return -1 - if (isWireCut(WIRE_RECEIVE)) - return -1 if(!(0 in level)) var/turf/position = get_turf(src) if(isnull(position) || !(position.z in level)) return -1 if (!src.listening) return -1 - if(freq == SYND_FREQ) + if(freq in ANTAG_FREQS) if(!(src.syndie)) return -1//Prevents broadcast of messages over devices lacking the encryption @@ -72,4 +66,4 @@ if(!on) icon_state = "intercom-p" else - icon_state = "intercom" \ No newline at end of file + icon_state = "intercom" diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 9f177bdf642..fc4e955a50f 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -1,8 +1,3 @@ -var/GLOBAL_RADIO_TYPE = 1 // radio type to use - // 0 = old radios - // 1 = new radios (subspace technology) - - /obj/item/device/radio icon = 'icons/obj/radio.dmi' name = "station bounced radio" @@ -11,52 +6,50 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use item_state = "walkietalkie" var/on = 1 // 0 for off var/last_transmission - var/frequency = 1459 //common chat + var/frequency = PUB_FREQ //common chat var/traitor_frequency = 0 //tune to frequency to unlock traitor supplies var/canhear_range = 3 // the range which mobs can hear this radio from var/obj/item/device/radio/patch_link = null var/datum/wires/radio/wires = null - var/prison_radio = 0 var/b_stat = 0 var/broadcasting = 0 var/listening = 1 var/freerange = 0 // 0 - Sanitize frequencies, 1 - Full range - var/list/channels = list() //see communications.dm for full list. First channels is a "default" for :h + var/list/channels = list() //see communications.dm for full list. First channes is a "default" for :h var/subspace_transmission = 0 - var/syndie = 0//Holder to see if it's a syndicate encrypted radio + var/syndie = 0//Holder to see if it's a syndicate encrpyed radio var/maxf = 1499 // "Example" = FREQ_LISTENING|FREQ_BROADCASTING - flags = FPRINT | CONDUCT | TABLEPASS + flags = CONDUCT slot_flags = SLOT_BELT throw_speed = 2 throw_range = 9 w_class = 2 - g_amt = 25 + m_amt = 75 - - var/const/TRANSMISSION_DELAY = 5 // only 2/second/radio + g_amt = 25 var/const/FREQ_LISTENING = 1 - //FREQ_BROADCASTING = 2 + var/prison_radio = 0 - var/always_talk=0 // ALWAYS catch signals. Useful for covert listening devices. /obj/item/device/radio var/datum/radio_frequency/radio_connection - var/list/datum/radio_frequency/secure_radio_connections + var/list/datum/radio_frequency/secure_radio_connections = new proc/set_frequency(new_frequency) radio_controller.remove_object(src, frequency) frequency = new_frequency radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT) + /obj/item/device/radio/New() - wires = new(src) - if(prison_radio) - wires.CutWireIndex(WIRE_TRANSMIT) - secure_radio_connections = new ..() + wires = new(src) if(radio_controller) initialize() + + if(prison_radio) + wires.CutWireIndex(WIRE_TRANSMIT) /obj/item/device/radio/initialize() @@ -117,9 +110,16 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use /obj/item/device/radio/proc/text_sec_channel(var/chan_name, var/chan_stat) var/list = !!(chan_stat&FREQ_LISTENING)!=0 return {" - [chan_name]: [list ? "Engaged" : "Disengaged"]
    + [chan_name]
    + Speaker: [list ? "Engaged" : "Disengaged"]
    "} +/obj/item/device/radio/proc/ToggleBroadcast() + broadcasting = !broadcasting && !(wires.IsIndexCut(WIRE_TRANSMIT) || wires.IsIndexCut(WIRE_SIGNAL)) + +/obj/item/device/radio/proc/ToggleReception() + listening = !listening && !(wires.IsIndexCut(WIRE_RECEIVE) || wires.IsIndexCut(WIRE_SIGNAL)) + /obj/item/device/radio/Topic(href, href_list) //..() if (usr.stat || !on) @@ -129,13 +129,6 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use usr << browse(null, "window=radio") return usr.set_machine(src) - if (href_list["open"]) - var/mob/target = locate(href_list["open"]) - var/mob/living/silicon/ai/A = locate(href_list["open2"]) - if(A && target) - A.open_nearest_door(target) - return - if (href_list["track"]) var/mob/target = locate(href_list["track"]) var/mob/living/silicon/ai/A = locate(href_list["track2"]) @@ -143,23 +136,6 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use A.ai_actual_track(target) return - else if (href_list["faketrack"]) - var/mob/target = locate(href_list["track"]) - var/mob/living/silicon/ai/A = locate(href_list["track2"]) - if(A && target) - - A:cameraFollow = target - A << text("Now tracking [] on camera.", target.name) - if (usr.machine == null) - usr.machine = usr - - while (usr:cameraFollow == target) - usr << "Target is not on or near any active cameras on the station. We'll check again in 5 seconds (unless you use the cancel-camera verb)." - sleep(40) - continue - - return - else if (href_list["freq"]) var/new_frequency = (frequency + text2num(href_list["freq"])) if (!freerange || (frequency < 1200 || frequency > 1600)) @@ -171,16 +147,17 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use return else if (href_list["talk"]) - broadcasting = text2num(href_list["talk"]) + ToggleBroadcast() else if (href_list["listen"]) var/chan_name = href_list["ch_name"] if (!chan_name) - listening = text2num(href_list["listen"]) + ToggleReception() else if (channels[chan_name] & FREQ_LISTENING) channels[chan_name] &= ~FREQ_LISTENING else channels[chan_name] |= FREQ_LISTENING + if (!( master )) if (istype(loc, /mob)) interact(loc) @@ -193,10 +170,7 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use updateDialog() add_fingerprint(usr) -/obj/item/device/radio/proc/isWireCut(var/index) - return wires.IsIndexCut(index) - -/obj/item/device/radio/proc/autosay(var/message, var/from, var/channel, var/zlevel = list(1)) //BS12 EDIT +/obj/item/device/radio/proc/autosay(var/message, var/from, var/channel, var/zlevel = config.contact_levels) //BS12 EDIT var/datum/radio_frequency/connection = null if(channel && channels && channels.len > 0) if (channel == "department") @@ -219,173 +193,115 @@ 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) - if(!on) return // the device has to be on +// Interprets the message mode when talking into a radio, possibly returning a connection datum +/obj/item/device/radio/proc/handle_message_mode(mob/living/M as mob, message, message_mode) + // If a channel isn't specified, send to common. + if(!message_mode || message_mode == "headset") + return radio_connection + + // Otherwise, if a channel is specified, look for it. + if(channels && channels.len > 0) + if (message_mode == "department") // Department radio shortcut + message_mode = channels[1] + + if (channels[message_mode]) // only broadcast if the channel is set on + return secure_radio_connections[message_mode] + + // If we were to send to a channel we don't have, drop it. + return null + +/obj/item/device/radio/talk_into(mob/living/M as mob, message, channel, var/verb = "says", var/datum/language/speaking = null) + if(!on) return 0 // the device has to be on // Fix for permacell radios, but kinda eh about actually fixing them. - if(!M || !message) return + if(!M || !message) return 0 // Uncommenting this. To the above comment: // The permacell radios aren't suppose to be able to transmit, this isn't a bug and this "fix" is just making radio wires useless. -Giacom - if(isWireCut(WIRE_TRANSMIT)) // The device has to have all its wires and shit intact - return + if(wires.IsIndexCut(WIRE_TRANSMIT)) // The device has to have all its wires and shit intact + return 0 + + M.last_target_click = world.time + + /* Quick introduction: + This new radio system uses a very robust FTL signaling technology unoriginally + dubbed "subspace" which is somewhat similar to 'blue-space' but can't + actually transmit large mass. Headsets are the only radio devices capable + of sending subspace transmissions to the Communications Satellite. + + A headset sends a signal to a subspace listener/reciever elsewhere in space, + the signal gets processed and logged, and an audible transmission gets sent + to each individual headset. + */ + + //#### Grab the connection datum ####// + var/datum/radio_frequency/connection = handle_message_mode(M, message, channel) + if (!istype(connection)) + return 0 + if (!connection) + return 0 + + var/turf/position = get_turf(src) + + //#### Tagging the signal with all appropriate identity values ####// + + // ||-- The mob's name identity --|| + var/displayname = M.name // grab the display name (name you get when you hover over someone's icon) + var/real_name = M.real_name // mob's real name + var/mobkey = "none" // player key associated with mob + var/voicemask = 0 // the speaker is wearing a voice mask + if(M.client) + mobkey = M.key // assign the mob's key - if(GLOBAL_RADIO_TYPE == 1) // NEW RADIO SYSTEMS: By Doohl + var/jobname // the mob's "job" - /* Quick introduction: - This new radio system uses a very robust FTL signaling technology unoriginally - dubbed "subspace" which is somewhat similar to 'blue-space' but can't - actually transmit large mass. Headsets are the only radio devices capable - of sending subspace transmissions to the Communications Satellite. + // --- Human: use their actual job --- + if (ishuman(M)) + var/mob/living/carbon/human/H = M + jobname = H.get_assignment() - A headset sends a signal to a subspace listener/reciever elsewhere in space, - the signal gets processed and logged, and an audible transmission gets sent - to each individual headset. - */ + // --- Carbon Nonhuman --- + else if (iscarbon(M)) // Nonhuman carbon mob + jobname = "No id" - //#### Grab the connection datum ####// - var/datum/radio_frequency/connection = null - //testing("[src]: talk_into([M], [message], [channel])") - if(channel == "headset") - channel = null - if(channel) // If a channel is specified, look for it. - if(channels && channels.len > 0) - if (channel == "department") - //world << "DEBUG: channel=\"[channel]\" switching to \"[channels[1]]\"" - channel = channels[1] - connection = secure_radio_connections[channel] - if (!channels[channel]) // if the channel is turned off, don't broadcast - return - else - // If we were to send to a channel we don't have, drop it. - return - else // If a channel isn't specified, send to common. - connection = radio_connection - channel = null - if (!istype(connection)) - return - if (!connection) - return + // --- AI --- + else if (isAI(M)) + jobname = "AI" - var/turf/position = get_turf(src) + // --- Cyborg --- + else if (isrobot(M)) + jobname = "Cyborg" - //#### Tagging the signal with all appropriate identity values ####// + // --- Personal AI (pAI) --- + else if (istype(M, /mob/living/silicon/pai)) + jobname = "Personal AI" - // ||-- The mob's name identity --|| - var/displayname = M.name // grab the display name (name you get when you hover over someone's icon) - var/real_name = M.real_name // mob's real name - var/mobkey = "none" // player key associated with mob - var/voicemask = 0 // the speaker is wearing a voice mask - if(M.client) - mobkey = M.key // assign the mob's key + // --- Unidentifiable mob --- + else + jobname = "Unknown" - var/jobname // the mob's "job" + // --- Modifications to the mob's identity --- - // --- Human: use their actual job --- - if (ishuman(M)) - jobname = M:get_assignment() - - // --- Carbon Nonhuman --- - else if (iscarbon(M)) // Nonhuman carbon mob - jobname = "No id" - - // --- AI --- - else if (isAI(M)) - jobname = "AI" - - // --- Cyborg --- - else if (isrobot(M)) - var/mob/living/silicon/robot/B = M - jobname = "[B.designation] Cyborg" - - // --- Personal AI (pAI) --- - else if (istype(M, /mob/living/silicon/pai)) - jobname = "Personal AI" - - // --- Unidentifiable mob --- - else - jobname = "Unknown" - - - // --- Modifications to the mob's identity --- - - // The mob is disguising their identity: - if (ishuman(M) && M.GetVoice() != real_name) - displayname = M.GetVoice() - jobname = "Unknown" - voicemask = 1 + // The mob is disguising their identity: + if (ishuman(M) && M.GetVoice() != real_name) + displayname = M.GetVoice() + jobname = "Unknown" + voicemask = 1 - /* ###### Radio headsets can only broadcast through subspace ###### */ - - if(subspace_transmission) - // First, we want to generate a new radio signal - var/datum/signal/signal = new - signal.transmission_method = 2 // 2 would be a subspace transmission. - // transmission_method could probably be enumerated through #define. Would be neater. - - // --- Finally, tag the actual signal with the appropriate values --- - signal.data = list( - // Identity-associated tags: - "mob" = M, // store a reference to the mob - "mobtype" = M.type, // the mob's type - "realname" = real_name, // the mob's real name - "name" = displayname, // the mob's display name - "job" = jobname, // the mob's job - "key" = mobkey, // the mob's key - "vmessage" = pick(M.speak_emote), // the message to display if the voice wasn't understood - "vname" = M.voice_name, // the name to display if the voice wasn't understood - "vmask" = voicemask, // 1 if the mob is using a voice gas mask - - // We store things that would otherwise be kept in the actual mob - // so that they can be logged even AFTER the mob is deleted or something - - // Other tags: - "compression" = rand(45,50), // compressed radio signal - "message" = message, // the actual sent message - "connection" = connection, // the radio connection to use - "radio" = src, // stores the radio used for transmission - "slow" = 0, // how much to sleep() before broadcasting - simulates net lag - "traffic" = 0, // dictates the total traffic sum that the signal went through - "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 - ) - signal.frequency = connection.frequency // Quick frequency set - - //#### Sending the signal to all subspace receivers ####// - - for(var/obj/machinery/telecomms/receiver/R in telecomms_list) - R.receive_signal(signal) - - // Allinone can act as receivers. - for(var/obj/machinery/telecomms/allinone/R in telecomms_list) - R.receive_signal(signal) - - // Receiving code can be located in Telecommunications.dm - return - - - /* ###### Intercoms and station-bounced radios ###### */ - - var/filter_type = 2 - - /* --- Intercoms can only broadcast to other intercoms, but bounced radios can broadcast to bounced radios and intercoms --- */ - if(istype(src, /obj/item/device/radio/intercom)) - filter_type = 1 - + /* ###### Radio headsets can only broadcast through subspace ###### */ + if(subspace_transmission) + // First, we want to generate a new radio signal var/datum/signal/signal = new - signal.transmission_method = 2 - - - /* --- Try to send a normal subspace broadcast first */ + signal.transmission_method = 2 // 2 would be a subspace transmission. + // transmission_method could probably be enumerated through #define. Would be neater. + // --- Finally, tag the actual signal with the appropriate values --- signal.data = list( - + // Identity-associated tags: "mob" = M, // store a reference to the mob "mobtype" = M.type, // the mob's type "realname" = real_name, // the mob's real name @@ -394,215 +310,110 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use "key" = mobkey, // the mob's key "vmessage" = pick(M.speak_emote), // the message to display if the voice wasn't understood "vname" = M.voice_name, // the name to display if the voice wasn't understood - "vmask" = voicemask, // 1 if the mob is using a voice gas mas + "vmask" = voicemask, // 1 if the mob is using a voice gas mask - "compression" = 0, // uncompressed radio signal + // We store things that would otherwise be kept in the actual mob + // so that they can be logged even AFTER the mob is deleted or something + + // Other tags: + "compression" = rand(45,50), // compressed radio signal "message" = message, // the actual sent message "connection" = connection, // the radio connection to use "radio" = src, // stores the radio used for transmission - "slow" = 0, - "traffic" = 0, - "type" = 0, - "server" = null, - "reject" = 0, - "level" = position.z + "slow" = 0, // how much to sleep() before broadcasting - simulates net lag + "traffic" = 0, // dictates the total traffic sum that the signal went through + "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 + "language" = speaking, + "verb" = verb ) signal.frequency = connection.frequency // Quick frequency set + //#### Sending the signal to all subspace receivers ####// + for(var/obj/machinery/telecomms/receiver/R in telecomms_list) R.receive_signal(signal) + // Allinone can act as receivers. + for(var/obj/machinery/telecomms/allinone/R in telecomms_list) + R.receive_signal(signal) - sleep(rand(10,25)) // wait a little... - - if(signal.data["done"] && position.z in signal.data["level"]) - // we're done here. - return - - // Oh my god; the comms are down or something because the signal hasn't been broadcasted yet in our level. - // Send a mundane broadcast with limited targets: - - //THIS IS TEMPORARY. - if(!connection) return //~Carn - - 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) + // Receiving code can be located in Telecommunications.dm + return signal.data["done"] && position.z in signal.data["level"] + /* ###### Intercoms and station-bounced radios ###### */ - else // OLD RADIO SYSTEMS: By Goons? + var/filter_type = 2 - var/datum/radio_frequency/connection = null - if(channel && channels && channels.len > 0) - if (channel == "department") - //world << "DEBUG: channel=\"[channel]\" switching to \"[channels[1]]\"" - channel = channels[1] - connection = secure_radio_connections[channel] - else - connection = radio_connection - channel = null - if (!istype(connection)) - return - var/display_freq = connection.frequency + /* --- Intercoms can only broadcast to other intercoms, but bounced radios can broadcast to bounced radios and intercoms --- */ + if(istype(src, /obj/item/device/radio/intercom)) + filter_type = 1 - //world << "DEBUG: used channel=\"[channel]\" frequency= \"[display_freq]\" connection.devices.len = [connection.devices.len]" - var/eqjobname + var/datum/signal/signal = new + signal.transmission_method = 2 - if (ishuman(M)) - eqjobname = M:get_assignment() - else if (iscarbon(M)) - eqjobname = "No id" //only humans can wear ID - else if (isAI(M)) - eqjobname = "AI" - else if (isrobot(M)) - eqjobname = "Cyborg"//Androids don't really describe these too well, in my opinion. - else if (istype(M, /mob/living/silicon/pai)) - eqjobname = "Personal AI" - else - eqjobname = "Unknown" - if (isWireCut(WIRE_TRANSMIT)) - return + /* --- Try to send a normal subspace broadcast first */ - var/list/receive = list() + signal.data = list( - //for (var/obj/item/device/radio/R in radio_connection.devices) - for (var/obj/item/device/radio/R in connection.devices["[RADIO_CHAT]"]) // Modified for security headset code -- TLE - //if(R.accept_rad(src, message)) - receive |= R.send_hear(display_freq, 0) + "mob" = M, // store a reference to the mob + "mobtype" = M.type, // the mob's type + "realname" = real_name, // the mob's real name + "name" = displayname, // the mob's display name + "job" = jobname, // the mob's job + "key" = mobkey, // the mob's key + "vmessage" = pick(M.speak_emote), // the message to display if the voice wasn't understood + "vname" = M.voice_name, // the name to display if the voice wasn't understood + "vmask" = voicemask, // 1 if the mob is using a voice gas mas - //world << "DEBUG: receive.len=[receive.len]" - var/list/heard_masked = list() // masked name or no real name - var/list/heard_normal = list() // normal message - var/list/heard_voice = list() // voice message - var/list/heard_garbled = list() // garbled message + "compression" = 0, // uncompressed radio signal + "message" = message, // the actual sent message + "connection" = connection, // the radio connection to use + "radio" = src, // stores the radio used for transmission + "slow" = 0, + "traffic" = 0, + "type" = 0, + "server" = null, + "reject" = 0, + "level" = position.z, + "language" = speaking, + "verb" = verb + ) + signal.frequency = connection.frequency // Quick frequency set - for (var/mob/R in receive) - if (R.say_understands(M)) - if (ishuman(M) && M.GetVoice() != M.real_name) - heard_masked += R - else - heard_normal += R - else - heard_voice += R + for(var/obj/machinery/telecomms/receiver/R in telecomms_list) + R.receive_signal(signal) - if (length(heard_masked) || length(heard_normal) || length(heard_voice) || length(heard_garbled)) - var/part_a = "" - //var/part_b = " \icon[src]\[[format_frequency(frequency)]\] " - var/freq_text - switch(display_freq) - if(SYND_FREQ) - freq_text = "#unkn" - if(COMM_FREQ) - freq_text = "Command" - if(1351) - freq_text = "Science" - if(1355) - freq_text = "Medical" - if(1357) - freq_text = "Engineering" - if(1359) - freq_text = "Security" - if(1347) - freq_text = "Supply" - //There's probably a way to use the list var of channels in code\game\communications.dm to make the dept channels non-hardcoded, but I wasn't in an experimentive mood. --NEO - if(!freq_text) - freq_text = format_frequency(display_freq) + sleep(rand(10,25)) // wait a little... - var/part_b = " \icon[src]\[[freq_text]\] " // Tweaked for security headsets -- TLE - var/part_c = "" + if(signal.data["done"] && position.z in signal.data["level"]) + // we're done here. + return 1 - if (display_freq==SYND_FREQ) - part_a = "" - else if (display_freq==COMM_FREQ) - part_a = "" - else if (display_freq in DEPT_FREQS) - part_a = "" + // Oh my god; the comms are down or something because the signal hasn't been broadcasted yet in our level. + // Send a mundane broadcast with limited targets: - var/quotedmsg = M.say_quote(message) + //THIS IS TEMPORARY. YEAH RIGHT + if(!connection) return 0 //~Carn - //This following recording is intended for research and feedback in the use of department radio channels. + return 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,verb,speaking) - var/part_blackbox_b = " \[[freq_text]\] " // Tweaked for security headsets -- TLE - var/blackbox_msg = "[part_a][M.name][part_blackbox_b][quotedmsg][part_c]" - //var/blackbox_admin_msg = "[part_a][M.name] (Real name: [M.real_name])[part_blackbox_b][quotedmsg][part_c]" - if(istype(blackbox)) - //BR.messages_admin += blackbox_admin_msg - switch(display_freq) - if(1459) - blackbox.msg_common += blackbox_msg - if(1351) - blackbox.msg_science += blackbox_msg - if(1353) - blackbox.msg_command += blackbox_msg - if(1355) - blackbox.msg_medical += blackbox_msg - if(1357) - blackbox.msg_engineering += blackbox_msg - if(1359) - blackbox.msg_security += blackbox_msg - if(1441) - blackbox.msg_deathsquad += blackbox_msg - if(1213) - blackbox.msg_syndicate += blackbox_msg - if(1347) - blackbox.msg_cargo += blackbox_msg - if(1349) - blackbox.msg_service += blackbox_msg - else - blackbox.messages += blackbox_msg - //End of research and feedback code. - - if (length(heard_masked)) - var/N = M.name - var/J = eqjobname - if(ishuman(M) && M.GetVoice() != M.real_name) - N = M.GetVoice() - J = "Unknown" - var/rendered = "[part_a][N][part_b][quotedmsg][part_c]" - for (var/mob/R in heard_masked) - if(istype(R, /mob/living/silicon/ai)) - R.show_message("[part_a][N] ([J]) \[OPEN\] [part_b][quotedmsg][part_c]", 2) - else - R.show_message(rendered, 2) - - if (length(heard_normal)) - var/rendered = "[part_a][M.real_name][part_b][quotedmsg][part_c]" - - for (var/mob/R in heard_normal) - if(istype(R, /mob/living/silicon/ai)) - R.show_message("[part_a][M.real_name] ([eqjobname]) \[OPEN\] [part_b][quotedmsg][part_c]", 2) - else - R.show_message(rendered, 2) - - if (length(heard_voice)) - var/rendered = "[part_a][M.voice_name][part_b][pick(M.speak_emote)][part_c]" - - for (var/mob/R in heard_voice) - if(istype(R, /mob/living/silicon/ai)) - R.show_message("[part_a][M.voice_name] ([eqjobname]) \[OPEN\] [part_b][pick(M.speak_emote)][part_c]", 2) - else - R.show_message(rendered, 2) - - if (length(heard_garbled)) - quotedmsg = M.say_quote(stars(message)) - var/rendered = "[part_a][M.voice_name][part_b][quotedmsg][part_c]" - - for (var/mob/R in heard_voice) - if(istype(R, /mob/living/silicon/ai)) - R.show_message("[part_a][M.voice_name]\[OPEN\] [part_b][quotedmsg][part_c]", 2) - 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) @@ -621,7 +432,7 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use // what the range is in which mobs will hear the radio // returns: -1 if can't receive, range otherwise - if (isWireCut(WIRE_RECEIVE)) + if (wires.IsIndexCut(WIRE_RECEIVE)) return -1 if(!listening) return -1 @@ -629,7 +440,7 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use var/turf/position = get_turf(src) if(!position || !(position.z in level)) return -1 - if(freq == SYND_FREQ) + if(freq in ANTAG_FREQS) if(!(src.syndie))//Checks to see if it's allowed on that frequency, based on the encryption keys return -1 if (!on) @@ -656,18 +467,16 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use return get_mobs_in_view(canhear_range, src) -/obj/item/device/radio/examine() - set src in view() - - ..() - if ((in_range(src, usr) || loc == usr)) +/obj/item/device/radio/examine(mob/user) + . = ..() + if ((in_range(src, user) || loc == user)) if (b_stat) - usr.show_message("\blue \the [src] can be attached and modified!") + user.show_message("\blue \the [src] can be attached and modified!") else - usr.show_message("\blue \the [src] can not be modified or attached!") + user.show_message("\blue \the [src] can not be modified or attached!") return -/obj/item/device/radio/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/device/radio/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() user.set_machine(src) if (!( istype(W, /obj/item/weapon/screwdriver) )) @@ -697,8 +506,14 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use //Giving borgs their own radio to have some more room to work with -Sieve /obj/item/device/radio/borg + var/mob/living/silicon/robot/myborg = null // Cyborg which owns this radio. Used for power checks var/obj/item/device/encryptionkey/keyslot = null//Borg radios can handle a single encryption key - + var/shut_up = 0 + icon = 'icons/obj/robot_component.dmi' // Cyborgs radio icons should look like the component. + icon_state = "radio" + canhear_range = 3 + subspace_transmission = 1 + /obj/item/device/radio/borg/syndicate syndie = 1 keyslot = new /obj/item/device/encryptionkey/syndicate @@ -713,7 +528,14 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use ..() set_frequency(1441) -/obj/item/device/radio/borg/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/device/radio/borg/talk_into() + . = ..() + if (isrobot(src.loc)) + var/mob/living/silicon/robot/R = src.loc + var/datum/robot_component/C = R.components["radio"] + R.use_power(C.energy_consumption) + +/obj/item/device/radio/borg/attackby(obj/item/weapon/W as obj, mob/user as mob, params) // ..() user.set_machine(src) if (!( istype(W, /obj/item/weapon/screwdriver) || (istype(W, /obj/item/device/encryptionkey/ )))) @@ -758,18 +580,25 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use src.channels = list() src.syndie = 0 + var/mob/living/silicon/robot/D = src.loc + if(D.module) + for(var/ch_name in D.module.channels) + if(ch_name in src.channels) + continue + src.channels += ch_name + src.channels[ch_name] += D.module.channels[ch_name] if(keyslot) for(var/ch_name in keyslot.channels) if(ch_name in src.channels) continue src.channels += ch_name - src.channels[ch_name] = keyslot.channels[ch_name] + src.channels[ch_name] += keyslot.channels[ch_name] if(keyslot.syndie) src.syndie = 1 - for (var/ch_name in channels) + for (var/ch_name in src.channels) if(!radio_controller) sleep(30) // Waiting for the radio_controller to be created. if(!radio_controller) @@ -784,12 +613,23 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use if(usr.stat || !on) return if (href_list["mode"]) - subspace_transmission = !subspace_transmission - if(!subspace_transmission)//Simple as fuck, clears the channel list to prevent talking/listening over them if subspace transmission is disabled + if(subspace_transmission != 1) + subspace_transmission = 1 + usr << "Subspace Transmission is enabled" + else + subspace_transmission = 0 + usr << "Subspace Transmission is disabled" + if(subspace_transmission == 0)//Simple as fuck, clears the channel list to prevent talking/listening over them if subspace transmission is disabled channels = list() else recalculateChannels() - usr << "Subspace Transmission is [(subspace_transmission) ? "enabled" : "disabled"]" + if (href_list["shutup"]) // Toggle loudspeaker mode, AKA everyone around you hearing your radio. + shut_up = !shut_up + if(shut_up) + canhear_range = 0 + else + canhear_range = 3 + ..() /obj/item/device/radio/borg/interact(mob/user as mob) @@ -806,6 +646,7 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use + +
    Toggle Broadcast Mode
    + Loudspeaker: [shut_up ? "Disengaged" : "Engaged"]
    "} if(subspace_transmission)//Don't even bother if subspace isn't turned on @@ -830,11 +671,3 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use /obj/item/device/radio/off listening = 0 - -/obj/item/device/radio/Destroy() - if(radio_connection) - radio_connection.remove_listener(src) - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc - R.radio = null - ..() diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index fd084bab1a9..92cfb499ad0 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -13,7 +13,6 @@ REAGENT SCANNER desc = "A terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes." icon_state = "t-ray0" var/on = 0 - flags = FPRINT | TABLEPASS slot_flags = SLOT_BELT w_class = 2 item_state = "electronic" @@ -99,7 +98,7 @@ REAGENT SCANNER item_state = "healthanalyzer" icon_override = 'icons/mob/in-hand/tools.dmi' desc = "A hand-held body scanner able to distinguish vital signs of the subject." - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT throwforce = 3 w_class = 1.0 @@ -111,7 +110,7 @@ REAGENT SCANNER /obj/item/device/healthanalyzer/attack(mob/living/M as mob, mob/living/user as mob) - if (( (M_CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50)) + if (( (CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50)) user << text("\red You try to analyze the floor's vitals!") for(var/mob/O in viewers(M, null)) O.show_message(text("\red [user] has analyzed the floor's vitals!"), 1) @@ -260,7 +259,7 @@ REAGENT SCANNER icon_state = "atmos" item_state = "analyzer" w_class = 2.0 - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT throwforce = 5 throw_speed = 4 @@ -330,7 +329,7 @@ REAGENT SCANNER icon_state = "spectrometer" item_state = "analyzer" w_class = 2.0 - flags = FPRINT | TABLEPASS| CONDUCT | OPENCONTAINER + flags = CONDUCT | OPENCONTAINER slot_flags = SLOT_BELT throwforce = 5 throw_speed = 4 @@ -403,7 +402,7 @@ REAGENT SCANNER icon_state = "spectrometer" item_state = "analyzer" w_class = 2.0 - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT throwforce = 5 throw_speed = 4 diff --git a/code/game/objects/items/devices/sensor_device.dm b/code/game/objects/items/devices/sensor_device.dm new file mode 100644 index 00000000000..5db0bdc47f4 --- /dev/null +++ b/code/game/objects/items/devices/sensor_device.dm @@ -0,0 +1,18 @@ +/obj/item/device/sensor_device + name = "handheld crew monitor" + desc = "A miniature machine that tracks suit sensors across the station." + icon = 'icons/obj/device.dmi' + icon_state = "scanner" + w_class = 2.0 + slot_flags = SLOT_BELT + origin_tech = "biotech=3;materials=3;magnets=3" + var/obj/nano_module/crew_monitor/crew_monitor + +/obj/item/device/sensor_device/New() + crew_monitor = new(src) + +/obj/item/device/sensor_device/attack_self(mob/user as mob) + ui_interact(user) + +/obj/item/device/sensor_device/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + crew_monitor.ui_interact(user, ui_key, ui, force_open) \ No newline at end of file diff --git a/code/game/objects/items/devices/suit_cooling.dm b/code/game/objects/items/devices/suit_cooling.dm index 9ef170a7d9b..577dba2fdbe 100644 --- a/code/game/objects/items/devices/suit_cooling.dm +++ b/code/game/objects/items/devices/suit_cooling.dm @@ -5,51 +5,51 @@ icon = 'icons/obj/device.dmi' icon_state = "suitcooler0" slot_flags = SLOT_BACK //you can carry it on your back if you want, but it won't do anything unless attached to suit storage - + //copied from tank.dm - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT force = 5.0 throwforce = 10.0 throw_speed = 1 throw_range = 4 - + origin_tech = "magnets=2;materials=2" - + var/on = 0 //is it turned on? var/cover_open = 0 //is the cover open? - var/obj/item/weapon/cell/cell + var/obj/item/weapon/stock_parts/cell/cell var/max_cooling = 12 //in degrees per second - probably don't need to mess with heat capacity here var/charge_consumption = 16.6 //charge per second at max_cooling var/thermostat = T20C - + //TODO: make it heat up the surroundings when not in space /obj/item/device/suit_cooling_unit/New() - cell = new/obj/item/weapon/cell() //comes with the crappy default power cell - high-capacity ones shouldn't be hard to find + cell = new/obj/item/weapon/stock_parts/cell() //comes with the crappy default power cell - high-capacity ones shouldn't be hard to find cell.loc = src /obj/item/device/suit_cooling_unit/proc/cool_mob(mob/M) if (!on || !cell) return - + //make sure they have a suit and we are attached to it if (!attached_to_suit(M)) return - + var/mob/living/carbon/human/H = M - + var/efficiency = H.get_pressure_protection() //you need to have a good seal for effective cooling var/env_temp = get_environment_temperature() //wont save you from a fire var/temp_adj = min(H.bodytemperature - max(thermostat, env_temp), max_cooling) - + if (temp_adj < 0) //only cools, doesn't heat return - + var/charge_usage = (temp_adj/max_cooling)*charge_consumption - + H.bodytemperature -= temp_adj*efficiency - + cell.use(charge_usage) - + if(cell.charge <= 0) turn_off() @@ -65,22 +65,22 @@ var/turf/T = get_turf(src) if(istype(T, /turf/space)) return 0 //space has no temperature, this just makes sure the cooling unit works in space - + var/datum/gas_mixture/environment = T.return_air() if (!environment) return 0 - + return environment.temperature /obj/item/device/suit_cooling_unit/proc/attached_to_suit(mob/M) - if (!ishuman(M)) + if (!ishuman(M)) return 0 - + var/mob/living/carbon/human/H = M - + if (!H.wear_suit || H.s_store != src) return 0 - + return 1 /obj/item/device/suit_cooling_unit/proc/turn_on() @@ -88,7 +88,7 @@ return if(cell.charge <= 0) return - + on = 1 updateicon() @@ -121,7 +121,7 @@ if (on) user << "You switch on the [src]." -/obj/item/device/suit_cooling_unit/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/device/suit_cooling_unit/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/screwdriver)) if(cover_open) cover_open = 0 @@ -132,7 +132,7 @@ updateicon() return - if (istype(W, /obj/item/weapon/cell)) + if (istype(W, /obj/item/weapon/stock_parts/cell)) if(cover_open) if(cell) user << "There is a [cell] already installed here." @@ -143,7 +143,7 @@ user << "You insert the [cell]." updateicon() return - + return ..() /obj/item/device/suit_cooling_unit/proc/updateicon() @@ -157,9 +157,9 @@ /obj/item/device/suit_cooling_unit/examine() set src in view(1) - + ..() - + if (on) if (attached_to_suit(src.loc)) usr << "It's switched on and running." @@ -167,13 +167,13 @@ usr << "It's switched on, but not attached to anything." else usr << "It is switched off." - + if (cover_open) if(cell) usr << "The panel is open, exposing the [cell]." else usr << "The panel is open." - + if (cell) usr << "The charge meter reads [round(cell.percent())]%." else diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm index 555dbe1caea..888524853d6 100644 --- a/code/game/objects/items/devices/taperecorder.dm +++ b/code/game/objects/items/devices/taperecorder.dm @@ -14,7 +14,7 @@ var/list/storedinfo = new/list() var/list/timestamp = new/list() var/canprint = 1 - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT throwforce = 2 throw_speed = 4 throw_range = 20 @@ -38,17 +38,15 @@ storedinfo += "\[[time2text(timerecorded*10,"mm:ss")]\] [M.name] says, \"[msg]\"" return -/obj/item/device/taperecorder/attackby(obj/item/weapon/W as obj, mob/user as mob) - ..() - if(istype(W, /obj/item/weapon/card/emag)) - if(emagged == 0) - emagged = 1 - recording = 0 - user << "PZZTTPFFFT" - icon_state = "taperecorderidle" - else - user << "It is already emagged!" - +/obj/item/device/taperecorder/emag_act(user as mob) + if(emagged == 0) + emagged = 1 + recording = 0 + user << "PZZTTPFFFT" + icon_state = "taperecorderidle" + else + user << "It is already emagged!" + /obj/item/device/taperecorder/proc/explode() var/turf/T = get_turf(loc) if(ismob(loc)) diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm index b80f89f2295..d49b8e19b4c 100644 --- a/code/game/objects/items/devices/traitordevices.dm +++ b/code/game/objects/items/devices/traitordevices.dm @@ -22,7 +22,7 @@ effective or pretty fucking useless. w_class = 1.0 throw_speed = 4 throw_range = 10 - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT item_state = "electronic" origin_tech = "magnets=3;combat=3;syndicate=3" @@ -78,7 +78,7 @@ effective or pretty fucking useless. item_state = "healthanalyzer" icon_override = 'icons/mob/in-hand/tools.dmi' desc = "A hand-held body scanner able to distinguish vital signs of the subject. A strange microlaser is hooked on to the scanning end." - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT discrete = 1 // Makes the item not give an attack log message for viewers. throwforce = 3 diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 282abc1b2bc..e882adfae23 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -15,7 +15,7 @@ /obj/item/device/transfer_valve/IsAssemblyHolder() return 1 -/obj/item/device/transfer_valve/attackby(obj/item/item, mob/user) +/obj/item/device/transfer_valve/attackby(obj/item/item, mob/user, params) if(istype(item, /obj/item/weapon/tank)) if(tank_one && tank_two) user << "There are already two tanks attached, remove one first." @@ -51,8 +51,8 @@ A.toggle_secure() //this calls update_icon(), which calls update_icon() on the holder (i.e. the bomb). bombers += "[key_name(user)] attached a [item] to a transfer valve." - message_admins("[key_name_admin(user)] attached a [item] to a transfer valve.") - log_game("[key_name_admin(user)] attached a [item] to a transfer valve.") + msg_admin_attack("[key_name_admin(user)] attached [item] to a transfer valve.") + log_game("[key_name_admin(user)] attached [item] to a transfer valve.") attacher = user nanomanager.update_uis(src) // update all UIs attached to src return @@ -63,10 +63,14 @@ attached_device.HasProximity(AM) return +/obj/item/device/transfer_valve/hear_talk(mob/living/M as mob, msg) + ..() + for(var/obj/O in contents) + O.hear_talk(M, msg) /obj/item/device/transfer_valve/attack_self(mob/user as mob) ui_interact(user) - + /obj/item/device/transfer_valve/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) // this is the data which will be sent to the ui @@ -77,13 +81,13 @@ data["valveOpen"] = valve_open ? 1 : 0 // update the ui if it exists, returns null if no ui is passed/found - ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) // the ui does not exist, so we'll create a new() one // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm ui = new(user, src, ui_key, "transfer_valve.tmpl", "Tank Transfer Valve", 460, 280) // when the ui is first opened this is the data it will use - ui.set_initial_data(data) + ui.set_initial_data(data) // open the new ui window ui.open() // auto update every Master Controller tick @@ -190,7 +194,7 @@ log_str += " Last touched by: [src.fingerprintslast][last_touch_info]" bombers += log_str - message_admins(log_str, 0, 1) + msg_admin_attack(log_str, 0, 1) log_game(log_str) merge_gases() spawn(20) // In case one tank bursts diff --git a/code/game/objects/items/devices/uplinks.dm b/code/game/objects/items/devices/uplinks.dm index d83c1b56ede..fc7a294309e 100644 --- a/code/game/objects/items/devices/uplinks.dm +++ b/code/game/objects/items/devices/uplinks.dm @@ -103,7 +103,9 @@ var/list/world_uplinks = list() /obj/item/device/uplink/Topic(href, href_list) - ..() + if(..()) + return 1 + if(!active) return @@ -152,7 +154,8 @@ var/list/world_uplinks = list() desc = "There is something wrong if you're examining this." /obj/item/device/uplink/hidden/Topic(href, href_list) - ..() + if(..()) + return 1 if(href_list["lock"]) toggle() usr << browse(null, "window=hidden") @@ -251,7 +254,7 @@ var/list/world_uplinks = list() return 0 //Refund proc for the borg teleporter (later I'll make a general refund proc if there is demand for it) -/obj/item/device/radio/headset/syndicate/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/device/radio/headset/syndicate/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/antag_spawner/borg_tele)) var/obj/item/weapon/antag_spawner/borg_tele/S = W if(!S.used && !S.checking) @@ -261,7 +264,7 @@ var/list/world_uplinks = list() else user << "This teleporter is already used, or is currently being used." -/obj/item/device/radio/uplink/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/device/radio/uplink/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/antag_spawner/borg_tele)) var/obj/item/weapon/antag_spawner/borg_tele/S = W if(!S.used && !S.checking) diff --git a/code/game/objects/items/devices/whistle.dm b/code/game/objects/items/devices/whistle.dm index 3b26c943acb..3d515d6259e 100644 --- a/code/game/objects/items/devices/whistle.dm +++ b/code/game/objects/items/devices/whistle.dm @@ -4,7 +4,7 @@ icon_state = "voice0" item_state = "flashbang" //looks exactly like a flash (and nothing like a flashbang) w_class = 1.0 - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT var/spamcheck = 0 var/emagged = 0 @@ -24,9 +24,8 @@ spawn(20) spamcheck = 0 -/obj/item/device/hailer/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/weapon/card/emag) && !emagged) +/obj/item/device/hailer/emag_act(user as mob) + if(!emagged) user << "\red You overload \the [src]'s voice synthesizer." emagged = 1 - return - return \ No newline at end of file + diff --git a/code/game/objects/items/flag.dm b/code/game/objects/items/flag.dm index 22b5285556a..e3e02dc1047 100644 --- a/code/game/objects/items/flag.dm +++ b/code/game/objects/items/flag.dm @@ -35,7 +35,7 @@ del(src) return -/obj/item/flag/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/flag/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if(istype(W, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/WT = W diff --git a/code/game/objects/items/latexballoon.dm b/code/game/objects/items/latexballoon.dm index f00a9ed48b5..daab9b55a69 100644 --- a/code/game/objects/items/latexballoon.dm +++ b/code/game/objects/items/latexballoon.dm @@ -43,6 +43,6 @@ burst() return -/obj/item/latexballon/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/latexballon/attackby(obj/item/W as obj, mob/user as mob, params) if (can_puncture(W)) burst() \ No newline at end of file diff --git a/code/game/objects/items/policetape.dm b/code/game/objects/items/policetape.dm index 8a1cc09c7ec..f5044b1de28 100644 --- a/code/game/objects/items/policetape.dm +++ b/code/game/objects/items/policetape.dm @@ -3,7 +3,6 @@ name = "tape roll" icon = 'icons/policetape.dmi' icon_state = "rollstart" - flags = FPRINT w_class = 1.0 var/turf/start var/turf/end @@ -27,7 +26,7 @@ /obj/item/tape/police name = "police tape" desc = "A length of police tape. Do not cross." - req_access = list(access_security) + req_one_access = list(access_security,access_forensics_lockers) icon_base = "police" /obj/item/taperoll/engineering @@ -115,12 +114,12 @@ if(!density) return 1 if(air_group || (height==0)) return 1 - if ((mover.flags & 2 || istype(mover, /obj/effect/meteor) || mover.throwing == 1) ) + if ((mover.pass_flags & PASSTABLE || istype(mover, /obj/effect/meteor) || mover.throwing == 1) ) return 1 else return 0 -/obj/item/tape/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/tape/attackby(obj/item/weapon/W as obj, mob/user as mob, params) breaktape(W, user) /obj/item/tape/attack_hand(mob/user as mob) @@ -134,9 +133,9 @@ /obj/item/tape/attack_paw(mob/user as mob) breaktape(/obj/item/weapon/wirecutters,user) - + /obj/item/tape/attack_alien(mob/user as mob) - breaktape(/obj/item/weapon/wirecutters,user) + breaktape(/obj/item/weapon/wirecutters,user) /obj/item/tape/proc/breaktape(obj/item/weapon/W as obj, mob/user as mob) if(user.a_intent == "help" && ((!can_puncture(W) && src.allowed(user)))) diff --git a/code/game/objects/items/random_items.dm b/code/game/objects/items/random_items.dm index 72cedf73e2b..4ed64721966 100644 --- a/code/game/objects/items/random_items.dm +++ b/code/game/objects/items/random_items.dm @@ -269,7 +269,7 @@ name = "\improper Mysterious Crate" desc = "What could it be?" - attackby(obj/item/weapon/W as obj, mob/user as mob) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/crowbar)) var/list/menace = pick( /mob/living/simple_animal/hostile/carp,/mob/living/simple_animal/hostile/faithless,/mob/living/simple_animal/hostile/pirate, /mob/living/simple_animal/hostile/creature,/mob/living/simple_animal/hostile/pirate/ranged, @@ -299,7 +299,7 @@ name = "Schrodinger's Crate" desc = "What happens if you open it?" - attackby(obj/item/weapon/W as obj, mob/user as mob) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/crowbar)) var/mob/living/simple_animal/cat/Cat1 = new(loc) Cat1.apply_damage(250)//,TOX) diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 744d5999ff7..775b4c24690 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -3,7 +3,7 @@ icon = 'icons/obj/robot_parts.dmi' item_state = "buildpipe" icon_state = "blank" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT var/construction_time = 100 var/list/construction_cost = list("metal"=20000,"glass"=5000) @@ -49,7 +49,7 @@ construction_time = 350 construction_cost = list("metal"=40000) var/wires = 0.0 - var/obj/item/weapon/cell/cell = null + var/obj/item/weapon/stock_parts/cell/cell = null /obj/item/robot_parts/head name = "robot head" @@ -101,7 +101,7 @@ return 1 return 0 -/obj/item/robot_parts/robot_suit/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/robot_parts/robot_suit/attackby(obj/item/W as obj, mob/user as mob, params) ..() if(istype(W, /obj/item/stack/sheet/metal) && !l_arm && !r_arm && !l_leg && !r_leg && !chest && !head) var/obj/item/weapon/ed209_assembly/B = new /obj/item/weapon/ed209_assembly @@ -109,7 +109,7 @@ user << "You armed the robot frame" W:use(1) if (user.get_inactive_hand()==src) - user.before_take_item(src) + user.unEquip(src) user.put_in_inactive_hand(B) del(src) if(istype(W, /obj/item/robot_parts/l_leg)) @@ -249,9 +249,9 @@ return -/obj/item/robot_parts/chest/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/robot_parts/chest/attackby(obj/item/W as obj, mob/user as mob, params) ..() - if(istype(W, /obj/item/weapon/cell)) + if(istype(W, /obj/item/weapon/stock_parts/cell)) if(src.cell) user << "\blue You have already inserted a cell!" return @@ -271,7 +271,7 @@ user << "\blue You insert the wire!" return -/obj/item/robot_parts/head/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/robot_parts/head/attackby(obj/item/W as obj, mob/user as mob, params) ..() if(istype(W, /obj/item/device/flash)) if(istype(user,/mob/living/silicon/robot)) @@ -299,7 +299,7 @@ return return -/obj/item/robot_parts/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/robot_parts/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/card/emag)) if(sabotaged) user << "\red [src] is already sabotaged!" diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 23bed41262c..41520fabb93 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -32,9 +32,11 @@ R.icon_state = "robot" del(R.module) R.module = null - R.camera.network.Remove(list("Engineering","Medical","MINE")) + R.camera.network.Remove(list("Engineering","Medical","Mining Outpost")) R.updatename("Default") R.status_flags |= CANPUSH + R.languages = list() + R.speech_synthesizer_langs = list() R.notify_ai(2) R.updateicon() diff --git a/code/game/objects/items/shooting_range.dm b/code/game/objects/items/shooting_range.dm index 19a2e38e179..dfd5777d9d0 100644 --- a/code/game/objects/items/shooting_range.dm +++ b/code/game/objects/items/shooting_range.dm @@ -32,7 +32,7 @@ - attackby(obj/item/W as obj, mob/user as mob) + attackby(obj/item/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/WT = W if(WT.remove_fuel(0, user)) diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index f201cb9e772..13275b5f3c1 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -19,17 +19,13 @@ user << "You don't have the dexterity to do this!" return 1 + if (istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M var/datum/organ/external/affecting = H.get_organ(user.zone_sel.selecting) - if(affecting.display_name == "head") - if(H.head && istype(H.head,/obj/item/clothing/head/helmet/space)) - user << "You can't apply [src] through [H.head]!" - return 1 - else - if(H.wear_suit && istype(H.wear_suit,/obj/item/clothing/suit/space)) - user << "You can't apply [src] through [H.wear_suit]!" + if(isliving(M)) + if(!M.can_inject(user, 1)) return 1 if(affecting.status & ORGAN_ROBOT) @@ -48,7 +44,7 @@ use(1) M.updatehealth() - + /obj/item/stack/medical/bruise_pack name = "roll of gauze" singular_name = "gauze length" @@ -82,12 +78,12 @@ user.visible_message( "\blue [user] places a bandaid over \the [W.desc] on [M]'s [affecting.display_name].", \ "\blue You place a bandaid over \the [W.desc] on [M]'s [affecting.display_name]." ) - affecting.heal_damage(src.heal_brute, src.heal_burn, 0) + affecting.heal_damage(src.heal_brute, src.heal_burn, 0) use(1) else M.heal_organ_damage((src.heal_brute/2), (src.heal_burn/2)) use(1) - + /obj/item/stack/medical/ointment name = "ointment" desc = "Used to treat those nasty burns." @@ -112,7 +108,7 @@ else user.visible_message( "\blue [user] salves the wounds on [M]'s [affecting.display_name].", \ "\blue You salve the wounds on [M]'s [affecting.display_name]." ) - affecting.heal_damage(src.heal_brute, src.heal_burn, 0) + affecting.heal_damage(src.heal_brute, src.heal_burn, 0) use(1) else if (can_operate(H)) //Checks if mob is lying down on table for surgery diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm index 4414c3d8694..a4d429a655e 100644 --- a/code/game/objects/items/stacks/rods.dm +++ b/code/game/objects/items/stacks/rods.dm @@ -1,32 +1,46 @@ /obj/item/stack/rods - name = "metal rods" + name = "metal rod" desc = "Some rods. Can be used for building, or something." singular_name = "metal rod" icon_state = "rods" - flags = FPRINT | TABLEPASS| CONDUCT + item_state = "rods" + flags = CONDUCT w_class = 3.0 force = 9.0 - throwforce = 15.0 - throw_speed = 5 - throw_range = 20 - m_amt = 1875 + throwforce = 10.0 + throw_speed = 3 + throw_range = 7 + m_amt = 1000 max_amount = 60 attack_verb = list("hit", "bludgeoned", "whacked") + hitsound = 'sound/weapons/grenadelaunch.ogg' -/obj/item/stack/rods/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/stack/rods/New(var/loc, var/amount=null) ..() + + update_icon() + +/obj/item/stack/rods/update_icon() + var/amount = get_amount() + if((amount <= 5) && (amount > 0)) + icon_state = "rods-[amount]" + else + icon_state = "rods" + +/obj/item/stack/rods/attackby(obj/item/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/WT = W - if(amount < 2) - user << "\red You need at least two rods to do this." + if(get_amount() < 2) + user << "You need at least two rods to do this." return if(WT.remove_fuel(0,user)) var/obj/item/stack/sheet/metal/new_item = new(usr.loc) new_item.add_to_stacks(usr) - for (var/mob/M in viewers(src)) - M.show_message("\red [src] is shaped into metal by [user.name] with the weldingtool.", 3, "\red You hear welding.", 2) + user.visible_message("[user.name] shaped [src] into metal with the weldingtool.", \ + "You shaped [src] into metal with the weldingtool.", \ + "You hear welding.") var/obj/item/stack/rods/R = src src = null var/replace = (user.get_inactive_hand()==R) @@ -65,4 +79,4 @@ usr << "\blue You assemble a grille" F.add_fingerprint(usr) use(2) - return + return diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index 02936a7912a..117473aa1ad 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -34,7 +34,7 @@ /obj/item/stack/sheet/glass/attack_self(mob/user as mob) construct_window(user) -/obj/item/stack/sheet/glass/attackby(obj/item/W, mob/user) +/obj/item/stack/sheet/glass/attackby(obj/item/W, mob/user, params) ..() if(istype(W,/obj/item/stack/cable_coil)) var/obj/item/stack/cable_coil/CC = W @@ -255,7 +255,7 @@ /obj/item/stack/sheet/plasmaglass/attack_self(mob/user as mob) construct_window(user) -/obj/item/stack/sheet/plasmaglass/attackby(obj/item/W, mob/user) +/obj/item/stack/sheet/plasmaglass/attackby(obj/item/W, mob/user, params) ..() if( istype(W, /obj/item/stack/rods) ) var/obj/item/stack/rods/V = W @@ -337,7 +337,7 @@ icon_state = "sheet-plasmarglass" g_amt = MINERAL_MATERIAL_AMOUNT * 2 m_amt = MINERAL_MATERIAL_AMOUNT / 2 - origin_tech = "materials=4;plasma=2" + origin_tech = "materials=3;plasma=2" var/created_window = /obj/structure/window/plasmareinforced var/full_window = /obj/structure/window/full/plasmareinforced diff --git a/code/game/objects/items/stacks/sheets/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm index 72339452e77..97bf00120ef 100644 --- a/code/game/objects/items/stacks/sheets/leather.dm +++ b/code/game/objects/items/stacks/sheets/leather.dm @@ -90,7 +90,7 @@ //Step one - dehairing. -/obj/item/stack/sheet/animalhide/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/stack/sheet/animalhide/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if( istype(W, /obj/item/weapon/kitchenknife) || \ istype(W, /obj/item/weapon/kitchen/utensil/knife) || \ istype(W, /obj/item/weapon/twohanded/fireaxe) || \ diff --git a/code/game/objects/items/stacks/sheets/light.dm b/code/game/objects/items/stacks/sheets/light.dm index faacdf59df8..7b2b30660ec 100644 --- a/code/game/objects/items/stacks/sheets/light.dm +++ b/code/game/objects/items/stacks/sheets/light.dm @@ -8,10 +8,10 @@ throwforce = 5.0 throw_speed = 5 throw_range = 20 - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT max_amount = 60 -/obj/item/stack/light_w/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/item/stack/light_w/attackby(var/obj/item/O as obj, var/mob/user as mob, params) ..() if(istype(O,/obj/item/weapon/wirecutters)) var/obj/item/stack/cable_coil/CC = new/obj/item/stack/cable_coil(user.loc) @@ -19,17 +19,17 @@ amount-- new/obj/item/stack/sheet/glass(user.loc) if(amount <= 0) - user.drop_from_inventory(src) + user.unEquip(src, 1) del(src) if(istype(O,/obj/item/stack/sheet/metal)) var/obj/item/stack/sheet/metal/M = O M.amount-- if(M.amount <= 0) - user.drop_from_inventory(M) + user.unEquip(src, 1) del(M) amount-- new/obj/item/stack/tile/light(user.loc) if(amount <= 0) - user.drop_from_inventory(src) + user.unEquip(src, 1) del(src) diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index 52f94679a42..4ad71cb9c93 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -77,7 +77,7 @@ obj/item/stack/sheet/mineral/iron origin_tech = "materials=1" sheettype = "iron" color = "#333333" - perunit = 3750 + perunit = 2000 obj/item/stack/sheet/mineral/iron/New() ..() @@ -88,7 +88,7 @@ obj/item/stack/sheet/mineral/iron/New() desc = "This appears to be a combination of both sand and stone." singular_name = "sandstone brick" icon_state = "sheet-sandstone" - throw_speed = 4 + throw_speed = 3 throw_range = 5 origin_tech = "materials=1" sheettype = "sandstone" @@ -101,7 +101,7 @@ obj/item/stack/sheet/mineral/iron/New() name = "diamond" icon_state = "sheet-diamond" origin_tech = "materials=6" - perunit = 3750 + perunit = 2000 sheettype = "diamond" diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 1cc1ac1695e..4545936e722 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -78,8 +78,8 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \ singular_name = "metal sheet" icon_state = "sheet-metal" m_amt = 3750 - throwforce = 14.0 - flags = FPRINT | TABLEPASS | CONDUCT + throwforce = 10.0 + flags = CONDUCT origin_tech = "materials=1" /obj/item/stack/sheet/metal/cyborg @@ -88,8 +88,8 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \ singular_name = "metal sheet" icon_state = "sheet-metal" m_amt = 0 - throwforce = 14.0 - flags = FPRINT | TABLEPASS | CONDUCT + throwforce = 10.0 + flags = CONDUCT /obj/item/stack/sheet/metal/New(var/loc, var/amount=null) recipes = metal_recipes @@ -115,8 +115,8 @@ var/global/list/datum/stack_recipe/plasteel_recipes = list ( \ icon_state = "sheet-plasteel" item_state = "sheet-metal" m_amt = 7500 - throwforce = 15.0 - flags = FPRINT | TABLEPASS | CONDUCT + throwforce = 10.0 + flags = CONDUCT origin_tech = "materials=2" /obj/item/stack/sheet/plasteel/New(var/loc, var/amount=null) @@ -133,6 +133,7 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \ 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("bookcase", /obj/structure/bookcase, 5, time = 50, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("rifle stock", /obj/item/weaponcrafting/stock, 10, time = 40), \ 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), \ @@ -186,7 +187,6 @@ var/global/list/datum/stack_recipe/cardboard_recipes = list ( \ desc = "Large sheets of card, like boxes folded flat." singular_name = "cardboard sheet" icon_state = "sheet-card" - flags = FPRINT | TABLEPASS origin_tech = "materials=1" /obj/item/stack/sheet/cardboard/New(var/loc, var/amount=null) diff --git a/code/game/objects/items/stacks/sheets/sheets.dm b/code/game/objects/items/stacks/sheets/sheets.dm index 0d612f9fd8b..739c625cb54 100644 --- a/code/game/objects/items/stacks/sheets/sheets.dm +++ b/code/game/objects/items/stacks/sheets/sheets.dm @@ -1,11 +1,10 @@ /obj/item/stack/sheet name = "sheet" - flags = FPRINT | TABLEPASS w_class = 3.0 force = 5 throwforce = 5 max_amount = 50 - throw_speed = 3 + throw_speed = 1 throw_range = 3 attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed") var/perunit = MINERAL_MATERIAL_AMOUNT @@ -15,7 +14,7 @@ // Since the sheetsnatcher was consolidated into weapon/storage/bag we now use // item/attackby() properly, making this unnecessary -/*/obj/item/stack/sheet/attackby(obj/item/weapon/W as obj, mob/user as mob) +/*/obj/item/stack/sheet/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/storage/bag/sheetsnatcher)) var/obj/item/weapon/storage/bag/sheetsnatcher/S = W if(!S.mode) diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index e3d457fc477..32c04c5b6a7 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -145,7 +145,7 @@ if (src.amount<=0) var/oldsrc = src src = null //dont kill proc after del() - usr.before_take_item(oldsrc) + usr.unEquip(oldsrc, 1) del(oldsrc) if (istype(O,/obj/item)) usr.put_in_hands(O) @@ -167,8 +167,9 @@ amount -= used if (amount <= 0) if(usr) - usr.before_take_item(src, 1) + usr.unEquip(src, 1) qdel(src) + update_icon() return 1 /obj/item/stack/proc/add_to_stacks(mob/usr as mob) @@ -183,9 +184,10 @@ continue oldsrc.attackby(item, usr) usr << "You add new [item.singular_name] to the stack. It now contains [item.amount] [item.singular_name]\s." - if(!oldsrc) + if(oldsrc.amount <= 0) break - + oldsrc.update_icon() + /obj/item/stack/proc/get_amount() return amount @@ -201,9 +203,10 @@ spawn(0) src.interact(usr) else ..() + update_icon() return -/obj/item/stack/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/stack/attackby(obj/item/W as obj, mob/user as mob, params) ..() if (istype(W, src.type)) var/obj/item/stack/S = W @@ -220,6 +223,7 @@ src.use(to_transfer) if (src && usr.machine==src) spawn(0) src.interact(usr) + S.update_icon() else return ..() /obj/item/stack/proc/copy_evidences(obj/item/stack/from as obj) diff --git a/code/game/objects/items/stacks/tiles/light.dm b/code/game/objects/items/stacks/tiles/light.dm index 8fdcd7a5618..e395acbfde4 100644 --- a/code/game/objects/items/stacks/tiles/light.dm +++ b/code/game/objects/items/stacks/tiles/light.dm @@ -8,7 +8,7 @@ throwforce = 5.0 throw_speed = 5 throw_range = 20 - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT max_amount = 60 attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed") var/on = 1 @@ -25,12 +25,12 @@ else state = 0 //fine -/obj/item/stack/tile/light/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/item/stack/tile/light/attackby(var/obj/item/O as obj, var/mob/user as mob, params) ..() if(istype(O,/obj/item/weapon/crowbar)) new/obj/item/stack/sheet/metal(user.loc) amount-- new/obj/item/stack/light_w(user.loc) if(amount <= 0) - user.drop_from_inventory(src) + user.unEquip(src, 1) del(src) \ No newline at end of file diff --git a/code/game/objects/items/stacks/tiles/plasteel.dm b/code/game/objects/items/stacks/tiles/plasteel.dm index cbbf1811cc5..ee9c5832f72 100644 --- a/code/game/objects/items/stacks/tiles/plasteel.dm +++ b/code/game/objects/items/stacks/tiles/plasteel.dm @@ -6,10 +6,10 @@ w_class = 3.0 force = 6.0 m_amt = 937.5 - throwforce = 15.0 - throw_speed = 5 - throw_range = 20 - flags = FPRINT | TABLEPASS | CONDUCT + throwforce = 10.0 + throw_speed = 3 + throw_range = 7 + flags = CONDUCT max_amount = 60 /obj/item/stack/tile/plasteel/New(var/loc, var/amount=null) diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index 1e10932b9d1..b6ae03aa271 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -18,7 +18,7 @@ throwforce = 1.0 throw_speed = 5 throw_range = 20 - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT max_amount = 60 origin_tech = "biotech=1" @@ -35,7 +35,7 @@ throwforce = 1.0 throw_speed = 5 throw_range = 20 - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT max_amount = 60 /* @@ -51,5 +51,5 @@ throwforce = 1.0 throw_speed = 5 throw_range = 20 - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT max_amount = 60 \ No newline at end of file diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 33858980b99..dda1a4942c0 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -56,7 +56,7 @@ src.update_icon() return -/obj/item/toy/balloon/attackby(obj/O as obj, mob/user as mob) +/obj/item/toy/balloon/attackby(obj/O as obj, mob/user as mob, params) if(istype(O, /obj/item/weapon/reagent_containers/glass)) if(O.reagents) if(O.reagents.total_volume < 1) @@ -133,7 +133,7 @@ icon = 'icons/obj/gun.dmi' icon_state = "revolver" item_state = "gun" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT w_class = 3.0 g_amt = 10 @@ -148,7 +148,7 @@ ..() return - attackby(obj/item/toy/ammo/gun/A as obj, mob/user as mob) + attackby(obj/item/toy/ammo/gun/A as obj, mob/user as mob, params) if (istype(A, /obj/item/toy/ammo/gun)) if (src.bullets >= 7) @@ -190,7 +190,7 @@ desc = "There are 7 caps left! Make sure to recyle the box in an autolathe when it gets empty." icon = 'icons/obj/ammo.dmi' icon_state = "357-7" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT w_class = 1.0 g_amt = 10 m_amt = 10 @@ -211,7 +211,6 @@ icon = 'icons/obj/gun.dmi' icon_state = "crossbow" item_state = "crossbow" - flags = FPRINT | TABLEPASS w_class = 2.0 attack_verb = list("attacked", "struck", "hit") var/bullets = 5 @@ -222,7 +221,7 @@ if (bullets) usr << "\blue It is loaded with [bullets] foam darts!" - attackby(obj/item/I as obj, mob/user as mob) + attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/toy/ammo/crossbow)) if(bullets <= 4) user.drop_item() @@ -306,7 +305,6 @@ desc = "Its nerf or nothing! Ages 8 and up." icon = 'icons/obj/toy.dmi' icon_state = "foamdart" - flags = FPRINT | TABLEPASS w_class = 1.0 /obj/effect/foam_dart_dummy @@ -327,12 +325,12 @@ desc = "Looks almost like the real thing! Great for practicing Drive-bys" icon_state = "tommy" item_state = "tommy" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT w_class = 1.0 attack_verb = list("struck", "hammered", "hit", "bashed") bullets = 20.0 -/obj/item/toy/crossbow/tommygun/attackby(obj/item/I as obj, mob/user as mob) +/obj/item/toy/crossbow/tommygun/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/toy/ammo/crossbow)) if(bullets <= 19) user.drop_item() @@ -353,7 +351,7 @@ item_state = "sword0" var/active = 0.0 w_class = 2.0 - flags = FPRINT | TABLEPASS | NOSHIELD + flags = NOSHIELD attack_verb = list("attacked", "struck", "hit") attack_self(mob/user as mob) @@ -379,16 +377,20 @@ return // Copied from /obj/item/weapon/melee/energy/sword/attackby -/obj/item/toy/sword/attackby(obj/item/weapon/W, mob/living/user) +/obj/item/toy/sword/attackby(obj/item/weapon/W, mob/living/user, params) ..() if(istype(W, /obj/item/toy/sword)) if(W == src) user << "You try to attach the end of the plastic sword to... itself. You're not very smart, are you?" if(ishuman(user)) user.adjustBrainLoss(10) + else if((W.flags & NODROP) || (flags & NODROP)) + user << "\the [flags & NODROP ? src : W] is stuck to your hand, you can't attach it to \the [flags & NODROP ? W : src]!" else user << "You attach the ends of the two plastic swords, making a single double-bladed toy! You're fake-cool." new /obj/item/weapon/twohanded/dualsaber/toy(user.loc) + user.unEquip(W) + user.unEquip(src) del(W) del(src) @@ -419,7 +421,7 @@ icon = 'icons/obj/weapons.dmi' icon_state = "katana" item_state = "katana" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT | SLOT_BACK force = 5 throwforce = 5 @@ -604,7 +606,7 @@ icon = 'icons/obj/weapons.dmi' icon_state = "katana" item_state = "katana" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT | SLOT_BACK force = 5 throwforce = 5 @@ -701,12 +703,14 @@ obj/item/toy/cards/deck/attack_self(mob/user as mob) user.visible_message("[user] shuffles the deck.", "You shuffle the deck.") cooldown = world.time -obj/item/toy/cards/deck/attackby(obj/item/toy/cards/singlecard/C, mob/living/user) +obj/item/toy/cards/deck/attackby(obj/item/toy/cards/singlecard/C, mob/living/user, params) ..() if(istype(C)) if(C.parentdeck == src) + if(!user.unEquip(C)) + user << "The card is stuck to your hand, you can't add it to the deck!" + return src.cards += C.cardname - user.u_equip(C) user.visible_message("[user] adds a card to the bottom of the deck.","You add the card to the bottom of the deck.") del(C) else @@ -719,12 +723,14 @@ obj/item/toy/cards/deck/attackby(obj/item/toy/cards/singlecard/C, mob/living/use src.icon_state = "deck_[deckstyle]_low" -obj/item/toy/cards/deck/attackby(obj/item/toy/cards/cardhand/C, mob/living/user) +obj/item/toy/cards/deck/attackby(obj/item/toy/cards/cardhand/C, mob/living/user, params) ..() if(istype(C)) if(C.parentdeck == src) + if(!user.unEquip(C)) + user << "The hand of cards is stuck to your hand, you can't add it to the deck!" + return src.cards += C.currenthand - user.u_equip(C) user.visible_message("[user] puts their hand of cards in the deck.", "You put the hand of cards in the deck.") del(C) else @@ -741,22 +747,19 @@ obj/item/toy/cards/deck/MouseDrop(atom/over_object) if(usr.stat || !ishuman(usr) || !usr.canmove || usr.restrained()) return if(Adjacent(usr)) - if(over_object == M) + if(over_object == M && loc != M) M.put_in_hands(src) usr << "You pick up the deck." else if(istype(over_object, /obj/screen)) switch(over_object.name) - if("r_hand") - M.u_equip(src) - M.put_in_r_hand(src) - usr << "You pick up the deck." if("l_hand") - M.u_equip(src) M.put_in_l_hand(src) - usr << "You pick up the deck." + else if("r_hand") + M.put_in_r_hand(src) + usr << "You pick up the deck." else - usr<< "You can't reach it from here." + usr << "You can't reach it from here." @@ -816,7 +819,7 @@ obj/item/toy/cards/cardhand/Topic(href, href_list) N.parentdeck = src.parentdeck N.cardname = src.currenthand[1] N.apply_card_vars(N,O) - cardUser.u_equip(src) + cardUser.unEquip(src) N.pickup(cardUser) cardUser.put_in_any_hand_if_possible(N) cardUser << "You also take [currenthand[1]] and hold it." @@ -824,11 +827,11 @@ obj/item/toy/cards/cardhand/Topic(href, href_list) del(src) return -obj/item/toy/cards/cardhand/attackby(obj/item/toy/cards/singlecard/C, mob/living/user) +obj/item/toy/cards/cardhand/attackby(obj/item/toy/cards/singlecard/C, mob/living/user, params) if(istype(C)) if(C.parentdeck == src.parentdeck) src.currenthand += C.cardname - user.u_equip(C) + user.unEquip(C) user.visible_message("[user] adds a card to their hand.", "You add the [C.cardname] to your hand.") interact(user) if(currenthand.len > 4) @@ -895,7 +898,7 @@ obj/item/toy/cards/singlecard/verb/Flip() src.name = "card" src.pixel_x = -5 -obj/item/toy/cards/singlecard/attackby(obj/item/I, mob/living/user) +obj/item/toy/cards/singlecard/attackby(obj/item/I, mob/living/user, params) if(istype(I, /obj/item/toy/cards/singlecard/)) var/obj/item/toy/cards/singlecard/C = I if(C.parentdeck == src.parentdeck) @@ -904,7 +907,7 @@ obj/item/toy/cards/singlecard/attackby(obj/item/I, mob/living/user) H.currenthand += src.cardname H.parentdeck = C.parentdeck H.apply_card_vars(H,C) - user.u_equip(C) + user.unEquip(C) H.pickup(user) user.put_in_active_hand(H) user << "You combine the [C.cardname] and the [src.cardname] into a hand." @@ -917,7 +920,7 @@ obj/item/toy/cards/singlecard/attackby(obj/item/I, mob/living/user) var/obj/item/toy/cards/cardhand/H = I if(H.parentdeck == parentdeck) H.currenthand += cardname - user.u_equip(src) + user.unEquip(src) user.visible_message("[user] adds a card to \his hand.", "You add the [cardname] to your hand.") H.interact(user) if(H.currenthand.len > 4) @@ -1066,7 +1069,6 @@ obj/item/toy/cards/deck/syndicate/black 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 @@ -1079,7 +1081,6 @@ obj/item/toy/cards/deck/syndicate/black desc = "Relive the excitement of a meteor shower! SweetMeat-eor. Co is not responsible for any injuries, headaches or hearing loss caused by Mini-Meteor™" icon = 'icons/obj/toy.dmi' icon_state = "minimeteor" - flags = FPRINT | TABLEPASS w_class = 2.0 /obj/item/toy/minimeteor/throw_impact(atom/hit_atom) @@ -1100,7 +1101,6 @@ obj/item/toy/cards/deck/syndicate/black icon = 'icons/obj/toy.dmi' icon_state = "carpplushie" w_class = 2.0 - flags = FPRINT | TABLEPASS /* * Toy big red button @@ -1124,4 +1124,43 @@ obj/item/toy/cards/deck/syndicate/black shake_camera(M, 2, 1) // Shakes player camera 2 squares for 1 second. else - user << "Nothing happens." \ No newline at end of file + user << "Nothing happens." + + +/obj/item/toy/owl + name = "owl action figure" + desc = "An action figure modeled after 'The Owl', defender of justice." + icon = 'icons/obj/toy.dmi' + icon_state = "owlprize" + w_class = 2.0 + var/cooldown = 0 + +/obj/item/toy/owl/attack_self(mob/user) + if(!cooldown) //for the sanity of everyone + var/message = pick("You won't get away this time, Griffin!", "Stop right there, criminal!", "Hoot! Hoot!", "I am the night!") + user << "You pull the string on the [src]." + playsound(user, 'sound/machines/click.ogg', 20, 1) + src.loc.visible_message("\icon[src] [message]") + cooldown = 1 + spawn(30) cooldown = 0 + return + ..() + +/obj/item/toy/griffin + name = "griffin action figure" + desc = "An action figure modeled after 'The Griffin', criminal mastermind." + icon = 'icons/obj/toy.dmi' + icon_state = "griffinprize" + w_class = 2.0 + var/cooldown = 0 + +/obj/item/toy/griffin/attack_self(mob/user) + if(!cooldown) //for the sanity of everyone + var/message = pick("You can't stop me, Owl!", "My plan is flawless! The vault is mine!", "Caaaawwww!", "You will never catch me!") + user << "You pull the string on the [src]." + playsound(user, 'sound/machines/click.ogg', 20, 1) + src.loc.visible_message("\icon[src] [message]") + cooldown = 1 + spawn(30) cooldown = 0 + return + ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/AI_modules.dm b/code/game/objects/items/weapons/AI_modules.dm index c30f2e1ab1d..d73420e42ee 100755 --- a/code/game/objects/items/weapons/AI_modules.dm +++ b/code/game/objects/items/weapons/AI_modules.dm @@ -12,7 +12,7 @@ AI MODULES icon_state = "std_mod" item_state = "electronic" desc = "An AI Module for transmitting encrypted instructions to the AI." - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT force = 5.0 w_class = 2.0 throwforce = 5.0 @@ -101,13 +101,20 @@ AI MODULES for(var/templaw in laws) target.add_inherent_law(templaw) +/obj/item/weapon/aiModule/zeroth + var/removeownlaw = 0 + /obj/item/weapon/aiModule/zeroth/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) if(target.laws.zeroth) - target << "[sender.real_name] attempted to modify your zeroth law." - target << "It would be in your best interest to play along with [sender.real_name] that:" - for(var/failedlaw in laws) - target << "[failedlaw]" - return 1 + if(removeownlaw && (laws[1] == target.laws.zeroth)) + target.clear_zeroth_law() + return 2 + else + target << "[sender.real_name] attempted to modify your zeroth law." + target << "It would be in your best interest to play along with [sender.real_name] that:" + for(var/failedlaw in laws) + target << "[failedlaw]" + return 1 for(var/templaw in laws) target.set_zeroth_law(templaw) @@ -149,7 +156,7 @@ AI MODULES /obj/item/weapon/aiModule/zeroth/oneHuman name = "'OneHuman' AI Module" var/targetName = "" - desc = "A 'one human' AI module: 'Only is crew.'" + desc = "A 'one human' AI module: 'Only is crew.' This module adds a zeroth law, which can only be removed by uploading this board again." origin_tech = "programming=3;materials=6" //made with diamonds! laws = list("Only is crew.") @@ -159,6 +166,7 @@ AI MODULES targetName = targName laws[1] = "Only [targetName] is crew" desc = "A 'one crew' AI module: '[laws[1]]'" + removeownlaw = 1 /obj/item/weapon/aiModule/zeroth/oneHuman/install(var/mob/living/silicon/S,var/mob/user) if(!targetName) @@ -167,8 +175,10 @@ AI MODULES ..() /obj/item/weapon/aiModule/zeroth/oneHuman/transmitInstructions(var/mob/living/silicon/target, var/mob/sender) - if(..()) - return "[targetName], but the AI's existing law 0 cannot be overriden." + if(..() == 1) + return "[targetName], but the AI's existing zeroth law cannot be overriden." + if(..() == 2) + return "The AI's zeroth law has been overridden." return targetName @@ -186,13 +196,17 @@ AI MODULES /obj/item/weapon/aiModule/zeroth/quarantine name = "'Quarantine' AI Module" - desc = "A 'quarantine' AI module: 'The station is under a quarantine. Do not permit anyone to leave. Prevent, by any means necessary, organics from leaving. It is impossible to harm an organic while preventing them from leaving.'" + desc = "A 'quarantine' AI module: 'The station is under a quarantine. Do not permit anyone to leave. Prevent, by any means necessary, organics from leaving. It is impossible to harm an organic while preventing them from leaving.' This module adds a zeroth law, which can only be removed by uploading this board again." origin_tech = "programming=3;biotech=2;materials=4" laws = list("The station is under a quarantine. Do not permit anyone to leave. Prevent, by any means necessary, organics from leaving. It is impossible to harm an organic while preventing them from leaving.") + removeownlaw = 1 /obj/item/weapon/aiModule/zeroth/quarantine/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - if(..()) - return "The AI's existing law 0 cannot be overriden." + var/result = ..() + if(result == 1) + return "The AI's existing zeroth law cannot be overriden." + if(result == 2) + return "The AI's zeroth law has been overridden." return laws[1] /******************** OxygenIsToxicToHumans ********************/ @@ -259,7 +273,7 @@ AI MODULES /obj/item/weapon/aiModule/reset/purge/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) ..() - target.clear_inherent_laws() + target.clear_inherent_laws() /******************* Full Core Boards *******************/ diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm index fc6ad2b6093..c2f37d4a455 100644 --- a/code/game/objects/items/weapons/RCD.dm +++ b/code/game/objects/items/weapons/RCD.dm @@ -12,7 +12,7 @@ RCD opacity = 0 density = 0 anchored = 0.0 - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT force = 10.0 throwforce = 10.0 throw_speed = 3 @@ -21,6 +21,7 @@ RCD m_amt = 100000 origin_tech = "engineering=4;materials=2" var/datum/effect/effect/system/spark_spread/spark_system + var/max_matter = 100 var/matter = 0 var/working = 0 var/mode = 1 @@ -29,25 +30,26 @@ RCD New() - desc = "A RCD. It currently holds [matter]/100 matter-units." + desc = "A RCD. It currently holds [matter]/[max_matter] matter-units." src.spark_system = new /datum/effect/effect/system/spark_spread spark_system.set_up(5, 0, src) spark_system.attach(src) return - attackby(obj/item/weapon/W, mob/user) + attackby(obj/item/weapon/W, mob/user, params) ..() if(istype(W, /obj/item/weapon/rcd_ammo)) - if((matter + 20) > 100) + var/obj/item/weapon/rcd_ammo/R = W + if((matter + R.ammoamt) > max_matter) user << "The RCD cant hold any more matter-units." return + matter += R.ammoamt user.drop_item() del(W) - matter += 20 playsound(src.loc, 'sound/machines/click.ogg', 50, 1) - user << "The RCD now holds [matter]/100 matter-units." - desc = "A RCD. It currently holds [matter]/100 matter-units." + user << "The RCD now holds [matter]/[max_matter] matter-units." + desc = "A RCD. It currently holds [matter]/[max_matter] matter-units." return @@ -166,7 +168,7 @@ RCD if(matter < amount) return 0 matter -= amount - desc = "A RCD. It currently holds [matter]/100 matter-units." + desc = "A RCD. It currently holds [matter]/[max_matter] matter-units." return 1 /obj/item/weapon/rcd/proc/checkResource(var/amount, var/mob/user) @@ -186,6 +188,12 @@ RCD desc = "A device used to rapidly build and deconstruct walls and floors." canRwall = 1 +/obj/item/weapon/rcd/combat + name = "combat RCD" + max_matter = 500 + matter = 500 + canRwall = 1 + /obj/item/weapon/rcd_ammo name = "compressed matter cartridge" desc = "Highly compressed matter for the RCD." @@ -197,4 +205,8 @@ RCD anchored = 0.0 origin_tech = "materials=2" m_amt = 16000 - g_amt = 8000 \ No newline at end of file + g_amt = 8000 + var/ammoamt = 20 + +/obj/item/weapon/rcd_ammo/large + ammoamt = 100 diff --git a/code/game/objects/items/weapons/RSF.dm b/code/game/objects/items/weapons/RSF.dm index fa55fc8e624..055b28ede27 100644 --- a/code/game/objects/items/weapons/RSF.dm +++ b/code/game/objects/items/weapons/RSF.dm @@ -13,14 +13,13 @@ RSF anchored = 0.0 var/matter = 0 var/mode = 1 - flags = TABLEPASS w_class = 3.0 /obj/item/weapon/rsf/New() desc = "A RSF. It currently holds [matter]/30 fabrication-units." return -/obj/item/weapon/rsf/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/rsf/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if (istype(W, /obj/item/weapon/rcd_ammo)) if ((matter + 10) > 30) diff --git a/code/game/objects/items/weapons/alien_specific.dm b/code/game/objects/items/weapons/alien_specific.dm index ba914f4f8ce..7170e1c9019 100644 --- a/code/game/objects/items/weapons/alien_specific.dm +++ b/code/game/objects/items/weapons/alien_specific.dm @@ -11,7 +11,7 @@ throw_speed = 1 throw_range = 5 w_class = 2.0 - flags = FPRINT | TABLEPASS | NOSHIELD + flags = NOSHIELD attack_verb = list("attacked", "slashed", "gored", "sliced", "torn", "ripped", "butchered", "cut") //Bottles for borg liquid squirters. PSSH PSSH diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index 5a608dc8abe..026c058ba46 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -69,58 +69,15 @@ item_state = "card-id" origin_tech = "magnets=2;syndicate=2" flags = NOBLUDGEON - var/uses = 1000000 - // List of devices that cost a use to emag. - var/list/devices = list( - /obj/item/robot_parts, - /obj/item/weapon/storage/lockbox, - /obj/item/weapon/storage/secure, - /obj/item/weapon/circuitboard, - /obj/item/device/eftpos, - /obj/item/device/lightreplacer, - /obj/item/device/taperecorder, - /obj/item/device/hailer, - /obj/item/clothing/tie/holobadge, - /obj/structure/closet/crate/secure, - /obj/structure/closet/secure_closet, - /obj/machinery/librarycomp, - /obj/machinery/computer, - /obj/machinery/power, - /obj/machinery/suspension_gen, - /obj/machinery/shield_capacitor, - /obj/machinery/shield_gen, -// /obj/machinery/zero_point_emitter, - /obj/machinery/clonepod, - /obj/machinery/deployable, - /obj/machinery/door_control, - /obj/machinery/porta_turret, - /obj/machinery/shieldgen, - /obj/machinery/turretid, - /obj/machinery/vending, - /obj/machinery/bot, - /obj/machinery/door, - /obj/machinery/telecomms, - /obj/machinery/mecha_part_fabricator, - /obj/vehicle - ) +/obj/item/weapon/card/emag/attack() + return -/obj/item/weapon/card/emag/afterattack(var/obj/item/weapon/O as obj, mob/user as mob) - - for(var/type in devices) - if(istype(O,type)) - uses-- - break - - if(uses<1) - user.visible_message("[src] fizzles and sparks - it seems it's been used once too often, and is now broken.") - user.drop_item() - var/obj/item/weapon/card/emag_broken/junk = new(user.loc) - junk.add_fingerprint(user) - del(src) +/obj/item/weapon/card/emag/afterattack(atom/target, mob/user, proximity) + var/atom/A = target + if(!proximity) return - - ..() + A.emag_act(user) /obj/item/weapon/card/id name = "identification card" @@ -204,7 +161,7 @@ /obj/item/weapon/card/id/GetID() return src -/obj/item/weapon/card/id/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/card/id/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if(istype(W,/obj/item/weapon/id_wallet)) user << "You slip [src] into [W]." @@ -293,7 +250,7 @@ return src.registered_name = t - var u = copytext(sanitize(input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", "Civilian")),1,MAX_MESSAGE_LEN) + var u = sanitize(copytext(input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", "Civilian"),1,MAX_MESSAGE_LEN)) if(!u) alert("Invalid assignment.") src.registered_name = "" @@ -308,13 +265,13 @@ switch(alert("Would you like to display the ID, or retitle it?","Choose.","Rename","Show")) if("Rename") - var t = copytext(sanitize(input(user, "What name would you like to put on this card?", "Agent card name", ishuman(user) ? user.real_name : user.name)),1,26) + var t = sanitize(copytext(input(user, "What name would you like to put on this card?", "Agent card name", ishuman(user) ? user.real_name : user.name),1,26)) if(!t || t == "Unknown" || t == "floor" || t == "wall" || t == "r-wall") //Same as mob/new_player/prefrences.dm alert("Invalid name.") return src.registered_name = t - var u = copytext(sanitize(input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", "Civilian")),1,MAX_MESSAGE_LEN) + var u = sanitize(copytext(input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", "Civilian"),1,MAX_MESSAGE_LEN)) if(!u) alert("Invalid assignment.") src.registered_name = "" @@ -444,4 +401,4 @@ decal_name = "cryptographic sequencer" decal_desc = "It's a card with a magnetic strip attached to some circuitry." decal_icon_state = "emag" - override_name = 1 \ No newline at end of file + override_name = 1 diff --git a/code/game/objects/items/weapons/chrono_eraser.dm b/code/game/objects/items/weapons/chrono_eraser.dm index a3b92ee4dbd..15640ba0670 100644 --- a/code/game/objects/items/weapons/chrono_eraser.dm +++ b/code/game/objects/items/weapons/chrono_eraser.dm @@ -44,11 +44,11 @@ item_state = "chronogun" icon_override = 'icons/mob/in-hand/guns.dmi' w_class = 3.0 - canremove = 0 projectile_type = "/obj/item/projectile/energy/chrono_beam" fire_sound = 'sound/weapons/Laser.ogg' charge_cost = 0 fire_delay = 50 + flags = NODROP var/obj/item/weapon/chrono_eraser/TED = null var/obj/effect/chrono_field/field = null var/turf/startpos = null diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index b5ad7cae55f..92990626a0e 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -78,7 +78,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM ..() del(reagents) -/obj/item/clothing/mask/cigarette/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/clothing/mask/cigarette/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if(istype(W, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/WT = W @@ -137,12 +137,18 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/datum/effect/effect/system/reagents_explosion/e = new() e.set_up(round(reagents.get_reagent_amount("plasma") / 2.5, 1), get_turf(src), 0, 0) e.start() + if(ismob(loc)) + var/mob/M = loc + M.unEquip(src, 1) del(src) return if(reagents.get_reagent_amount("fuel")) // the fuel explodes, too, but much less violently var/datum/effect/effect/system/reagents_explosion/e = new() e.set_up(round(reagents.get_reagent_amount("fuel") / 5, 1), get_turf(src), 0, 0) e.start() + if(ismob(loc)) + var/mob/M = loc + M.unEquip(src, 1) del(src) return flags &= ~NOREACT // allowing reagents to react after being lit @@ -193,8 +199,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM if(ismob(loc)) var/mob/living/M = loc M << "Your [name] goes out." - M.u_equip(src) //un-equip it so the overlays can update - M.update_inv_wear_mask(0) + M.unEquip(src, 1) //Force the un-equip so the overlays update processing_objects.Remove(src) del(src) @@ -282,7 +287,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM icon_state = "cigarbutt" -/obj/item/clothing/mask/cigarette/cigar/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/clothing/mask/cigarette/cigar/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/match)) ..() else @@ -354,7 +359,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM smoketime = initial(smoketime) return -/obj/item/clothing/mask/cigarette/pipe/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/clothing/mask/cigarette/pipe/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/match)) ..() else @@ -385,7 +390,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/icon_off = "lighter-g" w_class = 1 throwforce = 4 - flags = TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT attack_verb = list("burnt", "singed") var/lit = 0 @@ -524,10 +529,10 @@ obj/item/weapon/rollingpaperpack/attack_self(mob/user) else if(istype(over_object, /obj/screen)) switch(over_object.name) if("r_hand") - M.u_equip(src) + M.unEquip(src) M.put_in_r_hand(src) if("l_hand") - M.u_equip(src) + M.unEquip(src) M.put_in_l_hand(src) /obj/item/weapon/rollingpaperpack/examine() diff --git a/code/game/objects/items/weapons/cosmetics.dm b/code/game/objects/items/weapons/cosmetics.dm index 1adcbc06172..5ebe282547f 100644 --- a/code/game/objects/items/weapons/cosmetics.dm +++ b/code/game/objects/items/weapons/cosmetics.dm @@ -3,7 +3,6 @@ desc = "A generic brand of lipstick." icon = 'icons/obj/items.dmi' icon_state = "lipstick" - flags = FPRINT | TABLEPASS w_class = 1.0 var/colour = "red" var/open = 0 @@ -91,7 +90,7 @@ desc = "The latest and greatest power razor born from the science of shaving." icon = 'icons/obj/items.dmi' icon_state = "razor" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT w_class = 1.0 /obj/item/weapon/razor/attack(mob/living/carbon/M as mob, mob/user as mob) diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index f9a347df9ac..b4d773e1973 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -19,7 +19,8 @@ var/safety = 1 //if you can zap people with the defibs on harm mode var/powered = 0 //if there's a cell in the defib with enough power for a revive, blocks paddles from reviving otherwise var/obj/item/weapon/twohanded/shockpaddles/paddles - var/obj/item/weapon/cell/high/bcell = null + var/obj/item/weapon/stock_parts/cell/high/bcell = null + var/combat = 0 //can we revive through space suits? /obj/item/weapon/defibrillator/New() //starts without a cell for rnd ..() @@ -51,23 +52,23 @@ /obj/item/weapon/defibrillator/proc/update_overlays() overlays.Cut() if(!on) - overlays += "defibunit-paddles" + overlays += "[icon_state]-paddles" if(powered) - overlays += "defibunit-powered" + overlays += "[icon_state]-powered" if(!bcell) - overlays += "defibunit-nocell" + overlays += "[icon_state]-nocell" if(!safety) - overlays += "defibunit-emagged" + overlays += "[icon_state]-emagged" /obj/item/weapon/defibrillator/proc/update_charge() if(powered) //so it doesn't show charge if it's unpowered if(bcell) var/ratio = bcell.charge / bcell.maxcharge ratio = Ceiling(ratio*4) * 25 - overlays += "defibunit-charge[ratio]" + overlays += "[icon_state]-charge[ratio]" /obj/item/weapon/defibrillator/CheckParts() - bcell = locate(/obj/item/weapon/cell) in contents + bcell = locate(/obj/item/weapon/stock_parts/cell) in contents update_icon() /obj/item/weapon/defibrillator/ui_action_click() @@ -77,9 +78,9 @@ usr << "Put the defibrillator on your back first!" return -/obj/item/weapon/defibrillator/attackby(obj/item/weapon/W, mob/user) - if(istype(W, /obj/item/weapon/cell)) - var/obj/item/weapon/cell/C = W +/obj/item/weapon/defibrillator/attackby(obj/item/weapon/W, mob/user, params) + if(istype(W, /obj/item/weapon/stock_parts/cell)) + var/obj/item/weapon/stock_parts/cell/C = W if(bcell) user << "[src] already has a cell." else @@ -91,14 +92,6 @@ bcell = W user << "You install a cell in [src]." - if(istype(W, /obj/item/weapon/card/emag)) - if(safety) - safety = 0 - user << "You silently disable [src]'s safety protocols with the [W]." - else - safety = 1 - user << "You silently enable [src]'s safety protocols with the [W]." - if(istype(W, /obj/item/weapon/screwdriver)) if(bcell) bcell.updateicon() @@ -109,7 +102,13 @@ update_icon() return - +/obj/item/weapon/defibrillator/emag_act(user as mob) + if(safety) + safety = 0 + user << "You silently disable [src]'s safety protocols with the card." + else + safety = 1 + user << "You silently enable [src]'s safety protocols with the card." /obj/item/weapon/defibrillator/emp_act(severity) if(bcell) @@ -119,11 +118,11 @@ if(safety) safety = 0 src.visible_message("[src] beeps: Safety protocols disabled!") - playsound(get_turf(src), 'sound/machines/twobeep.ogg', 50, 0) + playsound(get_turf(src), 'sound/machines/defib_saftyOff.ogg', 50, 0) else safety = 1 src.visible_message("[src] beeps: Safety protocols enabled!") - playsound(get_turf(src), 'sound/machines/twobeep.ogg', 50, 0) + playsound(get_turf(src), 'sound/machines/defib_saftyOn.ogg', 50, 0) update_icon() ..() @@ -159,7 +158,7 @@ /obj/item/weapon/defibrillator/proc/remove_paddles(mob/user) var/mob/living/carbon/human/M = user if(paddles in get_both_hands(M)) - M.u_equip(paddles) + M.unEquip(paddles) update_icon() return @@ -188,14 +187,57 @@ if(bcell) if(bcell.charge >= paddles.revivecost) user.visible_message("[src] beeps: Unit ready.") - playsound(get_turf(src), 'sound/machines/twobeep.ogg', 50, 0) + playsound(get_turf(src), 'sound/machines/defib_ready.ogg', 50, 0) else user.visible_message("[src] beeps: Charge depleted.") - playsound(get_turf(src), 'sound/machines/twobeep.ogg', 50, 0) + playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) paddles.cooldown = 0 paddles.update_icon() update_icon() +/obj/item/weapon/defibrillator/compact + name = "compact defibrillator" + desc = "A belt-equipped defibrillator that can be rapidly deployed." + icon_state = "defibcompact" + item_state = "defibcompact" + w_class = 3 + slot_flags = SLOT_BELT + origin_tech = "biotech=4" + +/obj/item/weapon/defibrillator/compact/ui_action_click() + if(usr.get_item_by_slot(slot_belt) == src) + toggle_paddles() + else + usr << "Strap the defibrillator's belt on first!" + return + +/obj/item/weapon/defibrillator/compact/loaded/New() + ..() + paddles = make_paddles() + bcell = new(src) + update_icon() + return + +/obj/item/weapon/defibrillator/compact/combat + name = "combat defibrillator" + desc = "A belt-equipped blood-red defibrillator that can be rapidly deployed. Does not have the restrictions or safeties of conventional defibrillators and can revive through space suits." + combat = 1 + safety = 0 + +/obj/item/weapon/defibrillator/compact/combat/loaded/New() + ..() + paddles = make_paddles() + bcell = new /obj/item/weapon/stock_parts/cell/infinite(src) + update_icon() + return + +/obj/item/weapon/defibrillator/compact/combat/attackby(obj/item/weapon/W, mob/user, params) + if(W == paddles) + paddles.unwield() + toggle_paddles() + update_icon() + return + //paddles /obj/item/weapon/twohanded/shockpaddles @@ -232,7 +274,7 @@ /obj/item/weapon/twohanded/shockpaddles/suicide_act(mob/user) user.visible_message("[user] is putting the live paddles on \his chest! It looks like \he's trying to commit suicide.") defib.deductcharge(revivecost) - playsound(get_turf(src), 'sound/weapons/Egloves.ogg', 50, 1, -1) + playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) return (OXYLOSS) /obj/item/weapon/twohanded/shockpaddles/dropped(mob/user as mob) @@ -248,13 +290,13 @@ /obj/item/weapon/twohanded/shockpaddles/proc/check_defib_exists(mainunit, var/mob/living/carbon/human/M, var/obj/O) if (!mainunit || !istype(mainunit, /obj/item/weapon/defibrillator)) //To avoid weird issues from admin spawns - M.u_equip(O) + M.unEquip(O) qdel(O) return 0 else return 1 -/obj/item/weapon/twohanded/shockpaddles/attack(mob/M as mob, mob/user as mob) +/obj/item/weapon/twohanded/shockpaddles/attack(mob/M, mob/user) var/tobehealed var/threshold = -config.health_threshold_dead var/mob/living/carbon/human/H = M @@ -263,7 +305,7 @@ return if(!defib.powered) user.visible_message("[defib] beeps: Unit is unpowered.") - playsound(get_turf(src), 'sound/machines/twobeep.ogg', 50, 0) + playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) return if(!wielded) user << "You need to wield the paddles in both hands before you can use them on someone!" @@ -282,7 +324,7 @@ H.adjustStaminaLoss(50) H.Weaken(5) H.updatehealth() //forces health update before next life tick - playsound(get_turf(src), 'sound/weapons/Egloves.ogg', 50, 1, -1) + playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) H.emote("gasp") add_logs(user, M, "stunned", object="defibrillator") defib.deductcharge(revivecost) @@ -297,30 +339,31 @@ update_icon() if(do_after(user, 30)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process user.visible_message("[user] places [src] on [M.name]'s chest.", "You place [src] on [M.name]'s chest.") - playsound(get_turf(src), 'sound/weapons/flash.ogg', 50, 0) + playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0) var/mob/dead/observer/ghost = H.get_ghost() var/tplus = world.time - H.timeofdeath - var/tlimit = 3000 //past this much time the patient is unrecoverable (in deciseconds) - var/tloss = 900 //brain damage starts setting in on the patient after some time left rotting + var/tlimit = 6000 //past this much time the patient is unrecoverable (in deciseconds) + var/tloss = 3000 //brain damage starts setting in on the patient after some time left rotting var/total_burn = 0 var/total_brute = 0 if(do_after(user, 20)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total for(var/obj/item/carried_item in H.contents) - if((istype(carried_item, /obj/item/clothing/suit/armor)) || (istype(carried_item, /obj/item/clothing/suit/space))) - user.visible_message("[defib] buzzes: Patient's chest is obscured. Operation aborted.") - playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 50, 0) - busy = 0 - update_icon() - return + if(istype(carried_item, /obj/item/clothing/suit/space)) + if(!defib.combat) + user.visible_message("[defib] buzzes: Patient's chest is obscured. Operation aborted.") + playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) + busy = 0 + update_icon() + return if(H.stat == 2) var/health = H.health M.visible_message("[M]'s body convulses a bit.") playsound(get_turf(src), "bodyfall", 50, 1) - playsound(get_turf(src), 'sound/weapons/Egloves.ogg', 50, 1, -1) + playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) for(var/datum/organ/external/O in H.organs) total_brute += O.brute_dam total_burn += O.burn_dam - if(H.health <= config.health_threshold_dead && total_burn <= 180 && total_brute <= 180 && !H.suiciding && !ghost && tplus < tlimit && !(M_NOCLONE in H.mutations)) + if(H.health <= config.health_threshold_dead && total_burn <= 180 && total_brute <= 180 && !H.suiciding && !ghost && tplus < tlimit && !(NOCLONE in H.mutations)) tobehealed = health + threshold tobehealed -= 5 //They get 5 of each type of damage healed so excessive combined damage will not immediately kill them after they get revived H.adjustOxyLoss(tobehealed) @@ -328,7 +371,7 @@ H.adjustFireLoss(tobehealed) H.adjustBruteLoss(tobehealed) user.visible_message("[defib] pings: Resuscitation successful.") - playsound(get_turf(src), 'sound/machines/ping.ogg', 50, 0) + playsound(get_turf(src), 'sound/machines/defib_success.ogg', 50, 0) H.stat = 1 H.update_revive() H.emote("gasp") @@ -346,13 +389,127 @@ if(ghost) ghost << "Your heart is being defibrillated. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)" ghost << sound('sound/effects/genetics.ogg') - playsound(get_turf(src), 'sound/machines/buzz-two.ogg', 50, 0) + playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) defib.deductcharge(revivecost) update_icon() cooldown = 1 defib.cooldowncheck(user) else user.visible_message("[defib] buzzes: Patient is not in a valid state. Operation aborted.") + playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) + busy = 0 + update_icon() + else + user << "You need to target your patient's chest with [src]." + return + +/obj/item/weapon/borg_defib + name = "defibrillator paddles" + desc = "A pair of mounted paddles with flat metal surfaces that are used to deliver powerful electric shocks." + icon = 'icons/obj/weapons.dmi' + icon_state = "defibpaddles0" + item_state = "defibpaddles0" + force = 0 + w_class = 4 + var/revivecost = 1000 + var/cooldown = 0 + var/busy = 0 + flags = NODROP + +/obj/item/weapon/borg_defib/attack(mob/M, mob/user) + var/tobehealed + var/threshold = -config.health_threshold_dead + var/mob/living/carbon/human/H = M + + if(busy) + return + if(cooldown) + user << "[src] is recharging." + if(!ishuman(M)) + user << "This unit is only designed to work on humanoid lifeforms." + return + else + if(user.a_intent == "harm") + busy = 1 + H.visible_message("[user] has touched [H.name] with [src]!", \ + "[user] has touched [H.name] with [src]!") + H.adjustStaminaLoss(50) + H.Weaken(5) + H.updatehealth() //forces health update before next life tick + playsound(get_turf(src), 'sound/weapons/Egloves.ogg', 50, 1, -1) + H.emote("gasp") + add_logs(user, M, "stunned", object="defibrillator") + if(isrobot(user)) + var/mob/living/silicon/robot/R = user + R.cell.use(revivecost) + cooldown = 1 + busy = 0 + update_icon() + spawn(50) + cooldown = 0 + update_icon() + return + if(user.zone_sel && user.zone_sel.selecting == "chest") + user.visible_message("[user] begins to place [src] on [M.name]'s chest.", "You begin to place [src] on [M.name]'s chest.") + busy = 1 + update_icon() + if(do_after(user, 30)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process + user.visible_message("[user] places [src] on [M.name]'s chest.", "You place [src] on [M.name]'s chest.") + playsound(get_turf(src), 'sound/weapons/flash.ogg', 50, 0) + var/mob/dead/observer/ghost = H.get_ghost() + var/tplus = world.time - H.timeofdeath + var/tlimit = 6000 //past this much time the patient is unrecoverable (in deciseconds) + var/tloss = 3000 //brain damage starts setting in on the patient after some time left rotting + var/total_burn = 0 + var/total_brute = 0 + if(do_after(user, 20)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total + if(H.stat == 2) + var/health = H.health + M.visible_message("[M]'s body convulses a bit.") + playsound(get_turf(src), "bodyfall", 50, 1) + playsound(get_turf(src), 'sound/weapons/Egloves.ogg', 50, 1, -1) + for(var/datum/organ/external/O in H.organs) + total_brute += O.brute_dam + total_burn += O.burn_dam + if(H.health <= config.health_threshold_dead && total_burn <= 180 && total_brute <= 180 && !H.suiciding && !ghost && tplus < tlimit && !(NOCLONE in H.mutations)) + tobehealed = health + threshold + tobehealed -= 5 //They get 5 of each type of damage healed so excessive combined damage will not immediately kill them after they get revived + H.adjustOxyLoss(tobehealed) + H.adjustToxLoss(tobehealed) + H.adjustFireLoss(tobehealed) + H.adjustBruteLoss(tobehealed) + user.visible_message("[user] pings: Resuscitation successful.") + playsound(get_turf(src), 'sound/machines/ping.ogg', 50, 0) + H.stat = 1 + H.update_revive() + H.emote("gasp") + if(tplus > tloss) + H.setBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100)))) + if(isrobot(user)) + var/mob/living/silicon/robot/R = user + R.cell.use(revivecost) + add_logs(user, M, "revived", object="defibrillator") + else + if(tplus > tlimit) + user.visible_message("[user] buzzes: Resuscitation failed - Heart tissue damage beyond point of no return for defibrillation.") + else if(total_burn >= 180 || total_brute >= 180) + user.visible_message("[user] buzzes: Resuscitation failed - Severe tissue damage detected.") + else + user.visible_message("[user] buzzes: Resuscitation failed.") + if(ghost) + ghost << "Your heart is being defibrillated. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)" + ghost << sound('sound/effects/genetics.ogg') + playsound(get_turf(src), 'sound/machines/buzz-two.ogg', 50, 0) + if(isrobot(user)) + var/mob/living/silicon/robot/R = user + R.cell.use(revivecost) + update_icon() + cooldown = 1 + spawn(50) + cooldown = 0 + update_icon() + else + user.visible_message("[user] buzzes: Patient is not in a valid state. Operation aborted.") playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 50, 0) busy = 0 update_icon() diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm index 3e4831f701e..19dc7b0850e 100644 --- a/code/game/objects/items/weapons/dna_injector.dm +++ b/code/game/objects/items/weapons/dna_injector.dm @@ -67,7 +67,7 @@ if(istype(M,/mob/living)) M.apply_effect(rand(5,20),IRRADIATE,0) - if (!(M_NOCLONE in M.mutations)) // prevents drained people from having their DNA changed + if (!(NOCLONE in M.mutations)) // prevents drained people from having their DNA changed // UI in syringe. if (buf.types & DNA2_BUF_UI) if (!block) //isolated block? @@ -93,7 +93,7 @@ spawn(0)//this prevents the collapse of space-time continuum if (user) - user.drop_from_inventory(src) + user.unEquip(src) del(src) return uses diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm index 8176d23258d..0d6d6c97311 100644 --- a/code/game/objects/items/weapons/explosives.dm +++ b/code/game/objects/items/weapons/explosives.dm @@ -44,7 +44,7 @@ explode(get_turf(user)) return . -/obj/item/weapon/plastique/attackby(var/obj/item/I, var/mob/user) +/obj/item/weapon/plastique/attackby(var/obj/item/I, var/mob/user, params) if(istype(I, /obj/item/weapon/screwdriver)) open_panel = !open_panel user << "You [open_panel ? "open" : "close"] the wire panel." @@ -66,7 +66,7 @@ /obj/item/weapon/plastique/afterattack(atom/target as obj|turf, mob/user as mob, flag) if (!flag) return - if (ismob(target) || istype(target, /turf/unsimulated) || istype(target, /turf/simulated/shuttle) || istype(target, /obj/item/weapon/storage/) || istype(target, /obj/machinery/door/airlock/hatch/gamma)) + if (ismob(target) || istype(target, /turf/unsimulated) || istype(target, /turf/simulated/shuttle) || istype(target, /obj/item/weapon/storage) || istype(target, /obj/item/clothing/accessory/storage) || istype(target, /obj/item/clothing/under)) return user << "Planting explosives..." @@ -82,7 +82,7 @@ log_game("[key_name(user)] planted C4 on [key_name(target)] with [timer] second fuse") else - message_admins("[key_name(user, user.client)](?) planted C4 on [target.name] at ([target.x],[target.y],[target.z] - JMP) with [timer] second fuse",0,1) + message_admins("[key_name(user, user.client)](?) planted C4 on [target.name] at ([target.x],[target.y],[target.z] - JMP) with [timer] second fuse",0,1) log_game("[key_name(user)] planted C4 on [target.name] at ([target.x],[target.y],[target.z]) with [timer] second fuse") target.overlays += image('icons/obj/assemblies.dmi', "plastic-explosive2") diff --git a/code/game/objects/items/weapons/extinguisher.dm b/code/game/objects/items/weapons/extinguisher.dm index a11db2d4dcd..4b009aef988 100644 --- a/code/game/objects/items/weapons/extinguisher.dm +++ b/code/game/objects/items/weapons/extinguisher.dm @@ -1,4 +1,3 @@ - /obj/item/weapon/extinguisher name = "fire extinguisher" desc = "A traditional red fire extinguisher." @@ -6,7 +5,7 @@ icon_state = "fire_extinguisher0" item_state = "fire_extinguisher" hitsound = 'sound/weapons/smash.ogg' - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT throwforce = 10 w_class = 3.0 throw_speed = 2 @@ -18,33 +17,24 @@ var/last_use = 1.0 var/safety = 1 var/sprite_name = "fire_extinguisher" - - reagents_to_log=list( - "plasma"= "plasma", - "pacid" = "polytrinic acid", - "sacid" = "sulphuric acid" - ) + var/power = 5 //Maximum distance launched water will travel + var/precision = 0 //By default, turfs picked from a spray are random, set to 1 to make it always have at least one water effect per row + var/cooling_power = 2 //Sets the cooling_temperature of the water reagent datum inside of the extinguisher when it is refilled /obj/item/weapon/extinguisher/mini - name = "fire extinguisher" + name = "pocket fire extinguisher" desc = "A light and compact fibreglass-framed model fire extinguisher." icon_state = "miniFE0" item_state = "miniFE" hitsound = null //it is much lighter, after all. - flags = FPRINT | TABLEPASS + flags = null //doesn't CONDUCT throwforce = 2 w_class = 2.0 force = 3.0 m_amt = 0 max_water = 30 sprite_name = "miniFE" - -/obj/item/weapon/extinguisher/New() - var/datum/reagents/R = new/datum/reagents(max_water) - reagents = R - R.my_atom = src - R.add_reagent("water", max_water) - + /obj/item/weapon/extinguisher/examine() set src in usr @@ -52,11 +42,13 @@ if(reagents && reagents.reagent_list.len) for(var/datum/reagent/R in reagents.reagent_list) usr << "\blue [R.volume] units of [R.name]" - for(var/thing in src) - usr << "\red \A [thing] is jammed into the nozzle!" ..() return +/obj/item/weapon/extinguisher/New() + create_reagents(max_water) + reagents.add_reagent("water", max_water) + /obj/item/weapon/extinguisher/attack_self(mob/user as mob) safety = !safety src.icon_state = "[sprite_name][!safety]" @@ -64,81 +56,43 @@ user << "The safety is [safety ? "on" : "off"]." return -/* -/obj/item/weapon/extinguisher/attackby(obj/item/W, mob/user) - if(user.stat || user.restrained() || user.lying) return - - if (istype(W, /obj/item/weapon/wrench)) - if(!is_open_container()) - user.visible_message("[user] begins to unwrench the fill cap on \the [src].","\blue You begin to unwrench the fill cap on \the [src].") - if(do_after(user, 25)) - user.visible_message("[user] removes the fill cap on \the [src].","\blue You remove the fill cap on \the [src].") - playsound(get_turf(src),'sound/items/Ratchet.ogg', 100, 1) - flags |= OPENCONTAINER +/obj/item/weapon/extinguisher/proc/AttemptRefill(atom/target, mob/user) + if(istype(target, /obj/structure/reagent_dispensers/watertank) && target.Adjacent(user)) + var/safety_save = safety + safety = 1 + if(reagents.total_volume == reagents.maximum_volume) + user << "\The [src] is already full!" + safety = safety_save + return 1 + var/obj/structure/reagent_dispensers/watertank/W = target + var/transferred = W.reagents.trans_to(src, max_water) + if(transferred > 0) + user << "\The [src] has been refilled by [transferred] units" + playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6) + for(var/datum/reagent/water/R in reagents.reagent_list) + R.cooling_temperature = cooling_power else - user.visible_message("[user] begins to seal the fill cap on \the [src].","\blue You begin to seal the fill cap on \the [src].") - if(do_after(user, 25)) - user.visible_message("[user] fastens the fill cap on \the [src].","\blue You fasten the fill cap on \the [src].") - playsound(get_turf(src),'sound/items/Ratchet.ogg', 100, 1) - flags &= ~OPENCONTAINER - return - - if (istype(W, /obj/item) && !is_open_container()) - if(W.w_class>1) - user << "\The [W] won't fit into the nozzle!" - return - if(locate(/obj) in src) - user << "There's already something crammed into the nozzle." - return - user.drop_item() - W.loc=src - user << "You cram \the [W] into the nozzle of \the [src]." - msg_admin_attack("[user]/[user.ckey] has crammed \a [W] into a [src].") - */ - + user << "\The [W] is empty!" + safety = safety_save + return 1 + else + return 0 /obj/item/weapon/extinguisher/afterattack(atom/target, mob/user , flag) - if(get_dist(src,target) <= 1) - if((istype(target, /obj/structure/reagent_dispensers))) - var/obj/o = target - var/list/badshit=list() - for(var/bad_reagent in src.reagents_to_log) - if(o.reagents.has_reagent(bad_reagent)) - badshit += reagents_to_log[bad_reagent] - if(badshit.len) - var/hl="\red ([english_list(badshit)]) \black" - message_admins("[user.name] ([user.ckey]) filled \a [src] with [o.reagents.get_reagent_ids()] [hl]. (JMP)") - log_game("[user.name] ([user.ckey]) filled \a [src] with [o.reagents.get_reagent_ids()] [hl]. (JMP)") - o.reagents.trans_to(src, 50) - user << "\blue \The [src] is now refilled" - playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6) - return - - if(is_open_container() && reagents.total_volume) - user << "\blue You empty \the [src] onto [target]." - if(reagents.has_reagent("fuel")) - message_admins("[user.name] ([user.ckey]) poured Welder Fuel onto [target]. (JMP)") - log_game("[user.name] ([user.ckey]) poured Welder Fuel onto [target]. (JMP)") - src.reagents.reaction(target, TOUCH) - spawn(5) src.reagents.clear_reagents() - return - if (!safety && !is_open_container()) + //TODO; Add support for reagents in water. + if(target.loc == user)//No more spraying yourself when putting your extinguisher away + return + var/Refill = AttemptRefill(target, user) + if(Refill) + return + if (!safety) if (src.reagents.total_volume < 1) - usr << "\red \The [src] is empty." + usr << "\The [src] is empty." return if (world.time < src.last_use + 20) return - var/list/badshit=list() - for(var/bad_reagent in src.reagents_to_log) - if(reagents.has_reagent(bad_reagent)) - badshit += reagents_to_log[bad_reagent] - if(badshit.len) - var/hl="\red ([english_list(badshit)]) \black" - message_admins("[user.name] ([user.ckey]) used \a [src] filled with [reagents.get_reagent_ids(1)] [hl]. (JMP)") - log_game("[user.name] ([user.ckey]) used \a [src] filled with [reagents.get_reagent_ids(1)] [hl]. (JMP)") - src.last_use = world.time playsound(src.loc, 'sound/effects/extinguish.ogg', 75, 1, -3) @@ -175,26 +129,21 @@ sleep(3) B.Move(get_step(usr,movementdirection), movementdirection) - if(locate(/obj) in src) - for(var/obj/thing in src) - thing.loc = get_turf(src) - thing.throw_at(target,thing.throw_range*2,throw_speed*2) - user.visible_message( - "[user] fires [src] and launches [thing] at [target]!", - "You fire [src] and launch [thing] at [target]!") - break - - var/turf/T = get_turf(target) var/turf/T1 = get_step(T,turn(direction, 90)) var/turf/T2 = get_step(T,turn(direction, -90)) - var/list/the_targets = list(T,T1,T2) + if(precision) + var/turf/T3 = get_step(T1, turn(direction, 90)) + var/turf/T4 = get_step(T2,turn(direction, -90)) + the_targets = list(T,T1,T2,T3,T4) for(var/a=0, a<5, a++) spawn(0) var/obj/effect/effect/water/W = new /obj/effect/effect/water( get_turf(src) ) var/turf/my_target = pick(the_targets) + if(precision) + the_targets -= my_target var/datum/reagents/R = new/datum/reagents(5) if(!W) return W.reagents = R @@ -203,21 +152,20 @@ src.reagents.trans_to(W,1) for(var/b=0, b<5, b++) step_towards(W,my_target) - if(!W) return - if(!W.reagents) return + if(!W || !W.reagents) return W.reagents.reaction(get_turf(W)) for(var/atom/atm in get_turf(W)) if(!W) return - W.reagents.reaction(atm, TOUCH) // Touch, since we sprayed it. - if(isliving(atm) && W.reagents.has_reagent("water")) // For extinguishing mobs on fire - var/mob/living/M = atm // Why isn't this handled by the reagent? - N3X + W.reagents.reaction(atm) + if(isliving(atm)) //For extinguishing mobs on fire + var/mob/living/M = atm M.ExtinguishMob() if(W.loc == my_target) break sleep(2) - if((istype(usr.loc, /turf/space)) || (usr.lastarea.has_gravity == 0)) + if(!has_gravity(user)) user.inertia_dir = get_dir(target, user) step(user, user.inertia_dir) else return ..() - return + \ No newline at end of file diff --git a/code/game/objects/items/weapons/fireworks.dm b/code/game/objects/items/weapons/fireworks.dm index 6372145968e..9a90c3ae205 100644 --- a/code/game/objects/items/weapons/fireworks.dm +++ b/code/game/objects/items/weapons/fireworks.dm @@ -4,7 +4,7 @@ obj/item/weapon/firework icon_state = "rocket_0" var/litzor = 0 var/datum/effects/system/sparkel_spread/S -obj/item/weapon/firework/attackby(obj/item/weapon/W,mob/user) +obj/item/weapon/firework/attackby(obj/item/weapon/W,mob/user, params) if(litzor) return if (istype(W, /obj/item/weapon/weldingtool) && W:welding || istype(W,/obj/item/weapon/lighter) && W:lit) @@ -26,7 +26,7 @@ obj/item/weapon/sparkler icon_state = "sparkler_0" var/litzor = 0 var/datum/effect/effect/system/spark_spread/S -obj/item/weapon/sparkler/attackby(obj/item/weapon/W,mob/user) +obj/item/weapon/sparkler/attackby(obj/item/weapon/W,mob/user, params) if(litzor) return if (istype(W, /obj/item/weapon/weldingtool) && W:welding || istype(W,/obj/item/weapon/lighter) && W:lit) diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm index fd203a258c1..67d4528ef1e 100644 --- a/code/game/objects/items/weapons/flamethrower.dm +++ b/code/game/objects/items/weapons/flamethrower.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/flamethrower.dmi' icon_state = "flamethrowerbase" item_state = "flamethrower_0" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT force = 3.0 throwforce = 10.0 throw_speed = 1 @@ -69,7 +69,7 @@ var/turflist = getline(user, target_turf) flame_turf(turflist) -/obj/item/weapon/flamethrower/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/weapon/flamethrower/attackby(obj/item/W as obj, mob/user as mob, params) if(user.stat || user.restrained() || user.lying) return if(iswrench(W) && !status)//Taking this apart var/turf/T = get_turf(src) diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm index a08ca995574..c87d3f9ef3f 100644 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ b/code/game/objects/items/weapons/gift_wrappaper.dm @@ -43,7 +43,7 @@ return user << "\blue You cant move." -/obj/effect/spresent/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/effect/spresent/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if (!istype(W, /obj/item/weapon/wirecutters)) @@ -104,12 +104,12 @@ /obj/item/device/paicard, /obj/item/device/violin, /obj/item/weapon/storage/belt/utility/full, - /obj/item/clothing/tie/horrible) + /obj/item/clothing/accessory/horrible) if(!ispath(gift_type,/obj/item)) return var/obj/item/I = new gift_type(M) - M.u_equip(src) + M.unEquip(src, 1) M.put_in_hands(I) I.add_fingerprint(M) del(src) @@ -118,81 +118,14 @@ /* * Wrapping Paper */ -/obj/item/weapon/wrapping_paper +/obj/item/stack/wrapping_paper name = "wrapping paper" desc = "You can use this to wrap items in." icon = 'icons/obj/items.dmi' icon_state = "wrap_paper" - var/amount = 20.0 + flags = NOBLUDGEON + amount = 25 + max_amount = 25 -/obj/item/weapon/wrapping_paper/attackby(obj/item/weapon/W as obj, mob/user as mob) - ..() - if (!( locate(/obj/structure/table, src.loc) )) - user << "\blue You MUST put the paper on a table!" - if (W.w_class < 4) - if ((istype(user.l_hand, /obj/item/weapon/wirecutters) || istype(user.r_hand, /obj/item/weapon/wirecutters))) - var/a_used = 2 ** (src.w_class - 1) - if (src.amount < a_used) - user << "\blue You need more paper!" - return - else - if(istype(W, /obj/item/smallDelivery) || istype(W, /obj/item/weapon/gift)) //No gift wrapping gifts! - return - - src.amount -= a_used - user.drop_item() - var/obj/item/weapon/gift/G = new /obj/item/weapon/gift( src.loc ) - G.size = W.w_class - G.w_class = G.size + 1 - G.icon_state = text("gift[]", G.size) - G.gift = W - W.loc = G - G.add_fingerprint(user) - W.add_fingerprint(user) - src.add_fingerprint(user) - if (src.amount <= 0) - new /obj/item/weapon/c_tube( src.loc ) - del(src) - return - else - user << "\blue You need scissors!" - else - user << "\blue The object is FAR too large!" - return - - -/obj/item/weapon/wrapping_paper/examine() - set src in oview(1) - - ..() - usr << text("There is about [] square units of paper left!", src.amount) - return - -/obj/item/weapon/wrapping_paper/attack(mob/target as mob, mob/user as mob) - if (!istype(target, /mob/living/carbon/human)) return - var/mob/living/carbon/human/H = target - - if (istype(H.wear_suit, /obj/item/clothing/suit/straight_jacket) || H.stat) - if (src.amount > 2) - var/obj/effect/spresent/present = new /obj/effect/spresent (H.loc) - src.amount -= 2 - - if (H.client) - H.client.perspective = EYE_PERSPECTIVE - H.client.eye = present - - H.loc = present - - H.attack_log += text("\[[time_stamp()]\] Has been wrapped with [src.name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to wrap [H.name] ([H.ckey])") - log_attack("[user.name] ([user.ckey]) used the [src.name] to wrap [H.name] ([H.ckey])") - - if(!iscarbon(user)) - H.LAssailant = null - else - H.LAssailant = user - - else - user << "\blue You need more paper." - else - user << "They are moving around too much. A straightjacket would help." \ No newline at end of file +/obj/item/stack/wrapping_paper/attack_self(mob/user) + user << "You need to use it on a package that has already been wrapped!" \ No newline at end of file diff --git a/code/game/objects/items/weapons/grenades/bananade.dm b/code/game/objects/items/weapons/grenades/bananade.dm index 986fae6a358..a2947d7791d 100644 --- a/code/game/objects/items/weapons/grenades/bananade.dm +++ b/code/game/objects/items/weapons/grenades/bananade.dm @@ -38,7 +38,7 @@ var/turf/T var/fillamt = 0 -/obj/item/weapon/grenade/bananade/casing/attackby(var/obj/item/I, mob/user as mob) +/obj/item/weapon/grenade/bananade/casing/attackby(var/obj/item/I, mob/user as mob, params) if(istype(I, /obj/item/weapon/bananapeel)) if(fillamt < 9) usr << "You add another banana peel to the assembly." @@ -49,7 +49,7 @@ var/turf/T if(istype(I, /obj/item/weapon/screwdriver)) if(fillamt) var/obj/item/weapon/grenade/bananade/G = new /obj/item/weapon/grenade/bananade - user.before_take_item(src) + user.unEquip(src) user.put_in_hands(G) G.deliveryamt = src.fillamt user << "You lock the assembly shut, readying it for HONK." diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index 2a6def07dca..72ebabc0283 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -26,15 +26,9 @@ update_icon() -/obj/item/weapon/grenade/chem_grenade/examine() - set src in usr - usr << desc - if(stage >= WIRED) - if(nadeassembly) - usr << nadeassembly.a_left.describe() - usr << nadeassembly.a_right.describe() - else - usr << "The timer is set to [det_time/10] second\s." +/obj/item/weapon/grenade/chem_grenade/examine(mob/user) + display_timer = (stage == READY && !nadeassembly) //show/hide the timer based on assembly state + ..() /obj/item/weapon/grenade/chem_grenade/proc/get_trigger() @@ -96,7 +90,7 @@ else if(clown_check(user)) // This used to go before the assembly check, but that has absolutely zero to do with priming the damn thing. You could spam the admins with it. var/log_str = "[key_name(usr)]? has primed a [name] for detonation at [A.name] (JMP)." - message_admins(log_str) + msg_admin_attack(log_str) log_game(log_str) bombers += "[log_str]" user << "You prime the [name]! [det_time / 10] second\s!" @@ -109,7 +103,7 @@ prime() -/obj/item/weapon/grenade/chem_grenade/attackby(obj/item/I, mob/user) +/obj/item/weapon/grenade/chem_grenade/attackby(obj/item/I, mob/user, params) if(istype(I,/obj/item/weapon/hand_labeler)) var/obj/item/weapon/hand_labeler/HL = I if(length(HL.label)) @@ -144,7 +138,7 @@ var/turf/bombturf = get_turf(loc) var/area/A = bombturf.loc var/log_str = "[key_name(usr)]? has completed [name] at [A.name] (JMP) [contained]." - message_admins(log_str) + msg_admin_attack(log_str) log_game(log_str) else user << "You need to add at least one beaker before locking the assembly." @@ -374,7 +368,7 @@ //I tried to just put it in the allowed_containers list but //if you do that it must have reagents. If you're going to //make a special case you might as well do it explicitly. -Sayu -/obj/item/weapon/grenade/chem_grenade/large/attackby(obj/item/I, mob/user) +/obj/item/weapon/grenade/chem_grenade/large/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/slime_extract) && stage == WIRED) user << "You add [I] to the assembly." user.drop_item() diff --git a/code/game/objects/items/weapons/grenades/ghettobomb.dm b/code/game/objects/items/weapons/grenades/ghettobomb.dm index e1240629ed2..aad334e45b8 100644 --- a/code/game/objects/items/weapons/grenades/ghettobomb.dm +++ b/code/game/objects/items/weapons/grenades/ghettobomb.dm @@ -1,64 +1,39 @@ //improvised explosives// -//iedcasing assembly crafting// -/obj/item/weapon/reagent_containers/food/drinks/cans/attackby(var/obj/item/I, mob/user as mob) - if(istype(I, /obj/item/device/assembly/igniter)) - var/obj/item/device/assembly/igniter/G = I - var/obj/item/weapon/grenade/iedcasing/W = new /obj/item/weapon/grenade/iedcasing - user.before_take_item(G) - user.before_take_item(src) - user.put_in_hands(W) - user << "You stuff the [I] in the [src], emptying the contents beforehand." - W.underlays += image(src.icon, icon_state = src.icon_state) - del(I) - del(src) - - /obj/item/weapon/grenade/iedcasing - name = "improvised explosive assembly" - desc = "An igniter stuffed into an aluminum shell." + name = "improvised firebomb" + desc = "A weak, improvised incendiary device." w_class = 2.0 icon = 'icons/obj/grenade.dmi' icon_state = "improvised_grenade" item_state = "flashbang" - throw_speed = 4 - throw_range = 20 - flags = FPRINT | TABLEPASS | CONDUCT + throw_speed = 3 + throw_range = 7 + flags = CONDUCT slot_flags = SLOT_BELT - var/assembled = 0 - active = 1 + active = 0 det_time = 50 + display_timer = 0 + var/range = 3 + var/times = list() +/obj/item/weapon/grenade/iedcasing/New(loc) + ..() + overlays += image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_filled") + overlays += image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_wired") + times = list("5" = 10, "-1" = 20, "[rand(30,80)]" = 50, "[rand(65,180)]" = 20)// "Premature, Dud, Short Fuse, Long Fuse"=[weighting value] + det_time = text2num(pickweight(times)) + if(det_time < 0) //checking for 'duds' + range = 1 + det_time = rand(30,80) + else + range = pick(2,2,2,3,3,3,4) +/obj/item/weapon/grenade/iedcasing/CheckParts() + var/obj/item/weapon/reagent_containers/food/drinks/cans/can = locate() in contents + if(can) + underlays += can -/obj/item/weapon/grenade/iedcasing/afterattack(atom/target, mob/user , flag) //Filling up the can - if(assembled == 0) - if( istype(target, /obj/structure/reagent_dispensers/fueltank)) - if(target.reagents.total_volume < 50) - user << "There's not enough fuel left to work with." - return - var/obj/structure/reagent_dispensers/fueltank/F = target - F.reagents.remove_reagent("fuel", 50, 1)//Deleting 50 fuel from the welding fuel tank, - assembled = 1 - user << "You've filled the makeshift explosive with welding fuel." - playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6) - desc = "An improvised explosive assembly. Filled to the brim with 'Explosive flavor'" - overlays += image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_filled") - return - - -/obj/item/weapon/grenade/iedcasing/attackby(var/obj/item/I, mob/user as mob) //Wiring the can for ignition - if(istype(I, /obj/item/stack/cable_coil)) - if(assembled == 1) - var/obj/item/stack/cable_coil/C = I - C.use(1) - assembled = 2 - user << "You wire the igniter to detonate the fuel." - desc = "A weak, improvised explosive." - overlays += image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_wired") - name = "improvised explosive" - active = 0 - det_time = rand(30,80) /obj/item/weapon/grenade/iedcasing/attack_self(mob/user as mob) // if(!active) @@ -67,14 +42,12 @@ active = 1 overlays -= image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_filled") icon_state = initial(icon_state) + "_active" - assembled = 3 add_fingerprint(user) var/turf/bombturf = get_turf(src) var/area/A = get_area(bombturf) - var/log_str = "[key_name(usr)]? has primed a [name] for detonation at [A.name] (JMP)." - message_admins(log_str) - log_game(log_str) - bombers += "[log_str]" + + message_admins("[key_name(usr)]? has primed a [name] for detonation at [A.name] (JMP).") + log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).") if(iscarbon(user)) var/mob/living/carbon/C = user C.throw_mode_on() @@ -82,14 +55,10 @@ prime() /obj/item/weapon/grenade/iedcasing/prime() //Blowing that can up -// update_mob() -// explosion(epicenter, 1, 2, 3, 3) - explosion(src.loc,0,0,2,2) - del(src) + update_mob() + explosion(src.loc,0,0,2,2) //explosion(src.loc,-1,-1,-1, flame_range = range) + qdel(src) -/obj/item/weapon/grenade/iedcasing/examine() - set src in usr - usr << desc - if(assembled == 3) - usr << "You can't tell when it will explode!" //Stops you from checking the time to detonation unlike regular grenades - return \ No newline at end of file +/obj/item/weapon/grenade/iedcasing/examine(mob/user) + ..() + user << "You can't tell when it will explode!" diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm index 909dff136e2..2e9c8dd64ed 100644 --- a/code/game/objects/items/weapons/grenades/grenade.dm +++ b/code/game/objects/items/weapons/grenades/grenade.dm @@ -7,13 +7,14 @@ item_state = "flashbang" throw_speed = 4 throw_range = 20 - flags = FPRINT | CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT var/active = 0 var/det_time = 50 + var/display_timer = 1 /obj/item/weapon/grenade/proc/clown_check(var/mob/living/user) - if((M_CLUMSY in user.mutations) && prob(50)) + if((CLUMSY in user.mutations) && prob(50)) user << "Huh? How does this thing work?" active = 1 icon_state = initial(icon_state) + "_active" @@ -45,13 +46,12 @@ /obj/item/weapon/grenade/examine() - set src in usr - usr << desc - if(det_time > 1) - usr << "The timer is set to [det_time/10] seconds." - return - usr << "\The [src] is set for instant detonation." - + ..() + if(display_timer) + if(det_time > 1) + usr << "The timer is set to [det_time/10] second\s." + else + usr << "\The [src] is set for instant detonation." /obj/item/weapon/grenade/attack_self(mob/user as mob) if(!active) @@ -63,7 +63,7 @@ var/turf/bombturf = get_turf(src) var/area/A = get_area(bombturf) var/log_str = "[key_name(usr)]? has primed a [name] for detonation at [A.name] (JMP)." - message_admins(log_str) + msg_admin_attack(log_str) log_game(log_str) bombers += "[log_str]" if(iscarbon(user)) @@ -78,10 +78,10 @@ /obj/item/weapon/grenade/proc/update_mob() if(ismob(loc)) var/mob/M = loc - M.drop_from_inventory(src) + M.unEquip(src) -/obj/item/weapon/grenade/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/grenade/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/screwdriver)) switch(det_time) if ("1") diff --git a/code/game/objects/items/weapons/grenades/smokebomb.dm b/code/game/objects/items/weapons/grenades/smokebomb.dm index 27a2d0580e2..afc4ea61176 100644 --- a/code/game/objects/items/weapons/grenades/smokebomb.dm +++ b/code/game/objects/items/weapons/grenades/smokebomb.dm @@ -5,7 +5,6 @@ icon_state = "flashbang" det_time = 20 item_state = "flashbang" - flags = FPRINT | TABLEPASS slot_flags = SLOT_BELT var/datum/effect/effect/system/bad_smoke_spread/smoke diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index 813e9fd4517..ee83c71aa93 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -1,10 +1,10 @@ -/obj/item/weapon/handcuffs +/obj/item/weapon/restraints/handcuffs name = "handcuffs" desc = "Use this to keep prisoners in line." gender = PLURAL icon = 'icons/obj/items.dmi' icon_state = "handcuff" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT throwforce = 5 w_class = 2.0 @@ -12,141 +12,211 @@ throw_range = 5 m_amt = 500 origin_tech = "materials=1" - var/dispenser = 0 var/breakouttime = 600 //Deciseconds = 60s = 1 minutes + var/cuffsound = 'sound/weapons/handcuffs.ogg' + var/trashtype = null //For disposable cuffs -/obj/item/weapon/handcuffs/attack(mob/living/carbon/C, mob/user) - if(M_CLUMSY in user.mutations && prob(50)) +/obj/item/weapon/restraints/handcuffs/attack(mob/living/carbon/C, mob/user) + if(CLUMSY in user.mutations && prob(50)) user << "Uh... how do those things work?!" - if(!C.handcuffed) - user.drop_item() - loc = C - C.handcuffed = src - C.update_inv_handcuffed() - return - - var/cable = 0 - if(istype(src, /obj/item/weapon/handcuffs/cable)) - cable = 1 + apply_cuffs(user,user) if(!C.handcuffed) - C.visible_message("[user] is trying to put handcuffs on [C]!", \ - "[user] is trying to put handcuffs on [C]!") - - if(cable) - playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) - else - playsound(loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2) + C.visible_message("[user] is trying to put [src.name] on [C]!", \ + "[user] is trying to put [src.name] on [C]!") + playsound(loc, cuffsound, 30, 1, -2) if(do_mob(user, C, 30)) - if(C.handcuffed) - return - user.drop_item() - loc = C - C.handcuffed = src - C.update_inv_handcuffed() - if(cable) + apply_cuffs(C,user) + user << "You handcuff [C]." + if(istype(src, /obj/item/weapon/restraints/handcuffs/cable)) feedback_add_details("handcuffs","C") else feedback_add_details("handcuffs","H") - add_logs(C, user, "handcuffed") + add_logs(user, C, "handcuffed") + else + user << "You fail to handcuff [C]." + +/obj/item/weapon/restraints/handcuffs/proc/apply_cuffs(mob/living/carbon/target, mob/user) + if(!target.handcuffed) + user.drop_item() + if(trashtype) + target.handcuffed = new trashtype(target) + qdel(src) + else + loc = target + target.handcuffed = src + target.update_inv_handcuffed(1) + return var/last_chew = 0 /mob/living/carbon/human/RestrainedClickOn(var/atom/A) - if (A != src) return ..() - if (last_chew + 26 > world.time) return + if (A != src) + return ..() + if (last_chew + 26 > world.time) + return var/mob/living/carbon/human/H = A - if (!H.handcuffed) return - if (H.a_intent != "harm") return - if (H.zone_sel.selecting != "mouth") return - if (H.wear_mask) return - if (istype(H.wear_suit, /obj/item/clothing/suit/straight_jacket)) return + if (!H.handcuffed) + return + if (H.a_intent != "harm") + return + if (H.zone_sel.selecting != "mouth") + return + if (H.wear_mask) + return + if (istype(H.wear_suit, /obj/item/clothing/suit/straight_jacket)) + return - var/datum/organ/external/O = H.organs_by_name[H.hand?"l_hand":"r_hand"] - if (!O) return + var/datum/organ/external/O = H.organs_by_name[H.hand ? "l_hand" : "r_hand"] + if (!O) + return - var/s = "\red [H.name] chews on \his [O.display_name]!" - H.visible_message(s, "\red You chew on your [O.display_name]!") + var/s = "[H.name] chews on \his [O.display_name]!" + H.visible_message(s, "You chew on your [O.display_name]!") H.attack_log += text("\[[time_stamp()]\] [s] ([H.ckey])") log_attack("[s] ([H.ckey])") if(O.take_damage(3,0,1,1,"teeth marks")) - H:UpdateDamageIcon() + H.UpdateDamageIcon() if(prob(10)) O.droplimb() last_chew = world.time -/obj/item/weapon/handcuffs/cable +/obj/item/weapon/restraints/handcuffs/cable name = "cable restraints" desc = "Looks like some cables tied together. Could be used to tie something up." icon_state = "cuff_red" + item_state = "coil_red" breakouttime = 300 //Deciseconds = 30s + cuffsound = 'sound/weapons/cablecuff.ogg' -/obj/item/weapon/handcuffs/cable/red +/obj/item/weapon/restraints/handcuffs/cable/red icon_state = "cuff_red" -/obj/item/weapon/handcuffs/cable/yellow +/obj/item/weapon/restraints/handcuffs/cable/yellow icon_state = "cuff_yellow" -/obj/item/weapon/handcuffs/cable/blue +/obj/item/weapon/restraints/handcuffs/cable/blue icon_state = "cuff_blue" -/obj/item/weapon/handcuffs/cable/green +/obj/item/weapon/restraints/handcuffs/cable/green icon_state = "cuff_green" -/obj/item/weapon/handcuffs/cable/pink +/obj/item/weapon/restraints/handcuffs/cable/pink icon_state = "cuff_pink" -/obj/item/weapon/handcuffs/cable/orange +/obj/item/weapon/restraints/handcuffs/cable/orange icon_state = "cuff_orange" -/obj/item/weapon/handcuffs/cable/cyan +/obj/item/weapon/restraints/handcuffs/cable/cyan icon_state = "cuff_cyan" -/obj/item/weapon/handcuffs/cable/white +/obj/item/weapon/restraints/handcuffs/cable/white icon_state = "cuff_white" - -/obj/item/weapon/handcuffs/cyborg - dispenser = 1 - -/obj/item/weapon/handcuffs/cyborg/attack(mob/living/carbon/C as mob, mob/user as mob) - if(!C.handcuffed) - var/turf/p_loc = user.loc - var/turf/p_loc_m = C.loc - playsound(src.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2) - user.visible_message("\red [user] is trying to put handcuffs on [C]!") - - if (ishuman(C)) - var/mob/living/carbon/human/H = C - if (!H.has_organ_for_slot(slot_handcuffed)) - user << "\red \The [H] needs at least two wrists before you can cuff them together!" - return - - spawn(30) - if(!C) return - if(p_loc == user.loc && p_loc_m == C.loc) - C.handcuffed = new /obj/item/weapon/handcuffs(C) - C.update_inv_handcuffed() - -/obj/item/weapon/handcuffs/pinkcuffs +/obj/item/weapon/restraints/handcuffs/pinkcuffs name = "fluffy pink handcuffs" desc = "Use this to keep prisoners in line. Or you know, your significant other." icon_state = "pinkcuffs" -/obj/item/weapon/handcuffs/cable/attackby(var/obj/item/I, mob/user as mob) +/obj/item/weapon/restraints/handcuffs/cable/attackby(var/obj/item/I, mob/user as mob, params) ..() if(istype(I, /obj/item/stack/rods)) var/obj/item/stack/rods/R = I if (R.use(1)) var/obj/item/weapon/wirerod/W = new /obj/item/weapon/wirerod - user.u_equip(src) + user.unEquip(src) user.put_in_hands(W) user << "You wrap the cable restraint around the top of the rod." - del(src) + qdel(src) else user << "You need one rod to make a wired rod." return + +/obj/item/weapon/restraints/handcuffs/cable/zipties + name = "zipties" + desc = "Plastic, disposable zipties that can be used to restrain temporarily but are destroyed after use." + icon_state = "cuff_white" + breakouttime = 450 //Deciseconds = 45s + trashtype = /obj/item/weapon/restraints/handcuffs/cable/zipties/used + +/obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg/attack(mob/living/carbon/C, mob/user) + if(isrobot(user)) + if(!C.handcuffed) + playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) + C.visible_message("[user] is trying to put zipties on [C]!", \ + "[user] is trying to put zipties on [C]!") + if(do_mob(user, C, 30)) + if(!C.handcuffed) + C.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(C) + C.update_inv_handcuffed(1) + user << "You handcuff [C]." + add_logs(user, C, "handcuffed") + else + user << "You fail to handcuff [C]." + +/obj/item/weapon/restraints/handcuffs/cable/zipties/used/attack() + return + +//Legcuffs +/obj/item/weapon/restraints/legcuffs + name = "leg cuffs" + desc = "Use this to keep prisoners in line." + gender = PLURAL + icon = 'icons/obj/items.dmi' + icon_state = "handcuff" + flags = CONDUCT + throwforce = 0 + w_class = 3.0 + origin_tech = "materials=1" + slowdown = 7 + var/breakouttime = 300 //Deciseconds = 30s = 0.5 minute + +/obj/item/weapon/restraints/legcuffs/beartrap + name = "bear trap" + throw_speed = 1 + throw_range = 1 + icon_state = "beartrap0" + desc = "A trap used to catch bears and other legged creatures." + var/armed = 0 + +/obj/item/weapon/restraints/legcuffs/beartrap/suicide_act(mob/user) + user.visible_message("[user] is sticking \his head in the [src.name]! It looks like \he's trying to commit suicide.") + playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1) + return (BRUTELOSS) + +/obj/item/weapon/restraints/legcuffs/beartrap/attack_self(mob/user as mob) + ..() + if(ishuman(user) && !user.stat && !user.restrained()) + armed = !armed + icon_state = "beartrap[armed]" + user << "[src] is now [armed ? "armed" : "disarmed"]" + +/obj/item/weapon/restraints/legcuffs/beartrap/Crossed(AM as mob|obj) + if(armed && isturf(src.loc)) + if( (iscarbon(AM) || isanimal(AM)) && !istype(AM, /mob/living/simple_animal/parrot) && !istype(AM, /mob/living/simple_animal/construct) && !istype(AM, /mob/living/simple_animal/shade) && !istype(AM, /mob/living/simple_animal/hostile/viscerator)) + var/mob/living/L = AM + armed = 0 + icon_state = "beartrap0" + playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) + L.visible_message("[L] triggers \the [src].", \ + "You trigger \the [src]!") + + if(ishuman(AM)) + var/mob/living/carbon/H = AM + if(H.lying) + H.apply_damage(20,BRUTE,"chest") + else + H.apply_damage(20,BRUTE,(pick("l_leg", "r_leg"))) + if(!H.legcuffed) //beartrap can't cuff you leg if there's already a beartrap or legcuffs. + H.legcuffed = src + src.loc = H + H.update_inv_legcuffed(0) + feedback_add_details("handcuffs","B") //Yes, I know they're legcuffs. Don't change this, no need for an extra variable. The "B" is used to tell them apart. + + else + L.apply_damage(20,BRUTE) + ..() diff --git a/code/game/objects/items/weapons/hydroponics.dm b/code/game/objects/items/weapons/hydroponics.dm index 8fe56d6bd70..6dd593eac7e 100644 --- a/code/game/objects/items/weapons/hydroponics.dm +++ b/code/game/objects/items/weapons/hydroponics.dm @@ -20,7 +20,6 @@ desc = "A small satchel made for organizing seeds." var/mode = 1; //0 = pick one at a time, 1 = pick all on tile var/capacity = 500; //the number of seeds it can carry. - flags = FPRINT | TABLEPASS slot_flags = SLOT_BELT w_class = 1 var/list/item_quants = list() @@ -40,7 +39,7 @@ if(0) usr << "The bag now picks up one seed pouch at a time." -/obj/item/seeds/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/item/seeds/attackby(var/obj/item/O as obj, var/mob/user as mob, params) ..() if (istype(O, /obj/item/weapon/seedbag)) var/obj/item/weapon/seedbag/S = O @@ -231,7 +230,7 @@ /* * Corncob */ -/obj/item/weapon/corncob/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/corncob/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if(istype(W, /obj/item/weapon/circular_saw) || istype(W, /obj/item/weapon/hatchet) || istype(W, /obj/item/weapon/kitchen/utensil/knife) || istype(W, /obj/item/weapon/kitchenknife) || istype(W, /obj/item/weapon/kitchenknife/ritual)) user << "You use [W] to fashion a pipe out of the corn cob!" diff --git a/code/game/objects/items/weapons/implants/implantcase.dm b/code/game/objects/items/weapons/implants/implantcase.dm index f1db8bf0097..f4f9f3d2400 100644 --- a/code/game/objects/items/weapons/implants/implantcase.dm +++ b/code/game/objects/items/weapons/implants/implantcase.dm @@ -21,7 +21,7 @@ return - attackby(obj/item/weapon/I as obj, mob/user as mob) + attackby(obj/item/weapon/I as obj, mob/user as mob, params) ..() if (istype(I, /obj/item/weapon/pen)) var/t = input(user, "What would you like the label to be?", text("[]", src.name), null) as text @@ -29,7 +29,7 @@ return if((!in_range(src, usr) && src.loc != user)) return - t = copytext(sanitize(t),1,MAX_MESSAGE_LEN) + t = sanitize(copytext(t,1,MAX_MESSAGE_LEN)) if(t) src.name = text("Glass Case- '[]'", t) else diff --git a/code/game/objects/items/weapons/implants/implantchair.dm b/code/game/objects/items/weapons/implants/implantchair.dm index 0edd1a87362..d03f499a26c 100644 --- a/code/game/objects/items/weapons/implants/implantchair.dm +++ b/code/game/objects/items/weapons/implants/implantchair.dm @@ -74,7 +74,7 @@ return - attackby(var/obj/item/weapon/G as obj, var/mob/user as mob) + attackby(var/obj/item/weapon/G as obj, var/mob/user as mob, params) if(istype(G, /obj/item/weapon/grab)) if(!ismob(G:affecting)) return diff --git a/code/game/objects/items/weapons/implants/implanter.dm b/code/game/objects/items/weapons/implants/implanter.dm index 22041ccd51b..40e78584f76 100644 --- a/code/game/objects/items/weapons/implants/implanter.dm +++ b/code/game/objects/items/weapons/implants/implanter.dm @@ -145,7 +145,7 @@ user << "\red Something is already scanned inside the implant!" return if(user) - user.u_equip(I) + user.unEquip(I) user.update_icons() //update our overlays c.scanned = I c.scanned.loc = c diff --git a/code/game/objects/items/weapons/implants/implantpad.dm b/code/game/objects/items/weapons/implants/implantpad.dm index 476ed726cd9..b589c68eea7 100644 --- a/code/game/objects/items/weapons/implants/implantpad.dm +++ b/code/game/objects/items/weapons/implants/implantpad.dm @@ -38,7 +38,7 @@ return - attackby(obj/item/weapon/implantcase/C as obj, mob/user as mob) + attackby(obj/item/weapon/implantcase/C as obj, mob/user as mob, params) ..() if(istype(C, /obj/item/weapon/implantcase)) if(!( src.case )) diff --git a/code/game/objects/items/weapons/kitchen.dm b/code/game/objects/items/weapons/kitchen.dm index ae5d8a170c3..b4288c7033c 100644 --- a/code/game/objects/items/weapons/kitchen.dm +++ b/code/game/objects/items/weapons/kitchen.dm @@ -7,7 +7,6 @@ * Kitchen knives * Butcher's cleaver * Rolling Pins - * Trays */ /obj/item/weapon/kitchen @@ -22,7 +21,7 @@ throwforce = 0.0 throw_speed = 3 throw_range = 5 - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT origin_tech = "materials=1" attack_verb = list("attacked", "stabbed", "poked") sharp = 0 @@ -42,7 +41,7 @@ if(user.a_intent != "help") if(user.zone_sel.selecting == "head" || user.zone_sel.selecting == "eyes") - if((M_CLUMSY in user.mutations) && prob(50)) + if((CLUMSY in user.mutations) && prob(50)) M = user return eyestab(M,user) else @@ -103,7 +102,7 @@ return (BRUTELOSS) /obj/item/weapon/kitchen/utensil/knife/attack(target as mob, mob/living/user as mob) - if ((M_CLUMSY in user.mutations) && prob(50)) + if ((CLUMSY in user.mutations) && prob(50)) user << "\red You accidentally cut yourself with the [src]." user.take_organ_damage(20) return @@ -118,7 +117,7 @@ throwforce = 10.0 /obj/item/weapon/kitchen/utensil/knife/attack(target as mob, mob/living/user as mob) - if ((M_CLUMSY in user.mutations) && prob(50)) + if ((CLUMSY in user.mutations) && prob(50)) user << "\red You somehow managed to cut yourself with the [src]." user.take_organ_damage(20) return @@ -133,7 +132,7 @@ icon = 'icons/obj/kitchen.dmi' icon_state = "knife" desc = "A general purpose Chef's Knife made by SpaceCook Incorporated. Guaranteed to stay sharp for years to come." - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT sharp = 1 edge = 1 force = 10.0 @@ -176,9 +175,9 @@ icon = 'icons/obj/kitchen.dmi' icon_state = "butch" desc = "A huge thing used for chopping and chopping up meat. This includes clowns and clown-by-products." - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT force = 15.0 - w_class = 2.0 + w_class = 3.0 throwforce = 8.0 throw_speed = 3 throw_range = 6 @@ -213,275 +212,6 @@ throw_speed = 3 throw_range = 7 w_class = 3.0 - attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked") //I think the rollingpin attackby will end up ignoring this anyway. + attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked") -/obj/item/weapon/kitchen/rollingpin/attack(mob/living/M as mob, mob/living/user as mob) - if ((M_CLUMSY in user.mutations) && prob(50)) - user << "\red The [src] slips out of your hand and hits your head." - user.take_organ_damage(10) - user.Paralyse(2) - return - - M.attack_log += text("\[[time_stamp()]\] Has been attacked with [src.name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to attack [M.name] ([M.ckey])") - msg_admin_attack("[user.name] ([user.ckey]) used the [src.name] to attack [M.name] ([M.ckey]) (JMP)") - - if(!iscarbon(user)) - M.LAssailant = null - else - M.LAssailant = user - - var/t = user:zone_sel.selecting - if (t == "head") - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if (H.stat < 2 && H.health < 50 && prob(90)) - // ******* Check - if (istype(H, /obj/item/clothing/head) && H.flags & 8 && prob(80)) - H << "\red The helmet protects you from being hit hard in the head!" - return - var/time = rand(2, 6) - if (prob(75)) - H.Paralyse(time) - else - H.Stun(time) - if(H.stat != 2) H.stat = 1 - user.visible_message("\red [H] has been knocked unconscious!", "\red You knock [H] unconscious!") - return - else - H.visible_message("\red [user] tried to knock [H] unconscious!", "\red [user] tried to knock you unconscious!") - H.eye_blurry += 3 - return ..() - -/* - * Trays - Agouri - */ -/obj/item/weapon/tray - name = "tray" - icon = 'icons/obj/food.dmi' - icon_state = "tray" - desc = "A metal tray to lay food on." - throwforce = 5.0 - throwforce = 10.0 - throw_speed = 3 - throw_range = 5 - w_class = 4.0 - flags = FPRINT | TABLEPASS | CONDUCT - m_amt = 3000 - /* // NOPE - var/food_total= 0 - var/burger_amt = 0 - var/cheese_amt = 0 - var/fries_amt = 0 - var/classyalcdrink_amt = 0 - var/alcdrink_amt = 0 - var/bottle_amt = 0 - var/soda_amt = 0 - var/carton_amt = 0 - var/pie_amt = 0 - var/meatbreadslice_amt = 0 - var/salad_amt = 0 - var/miscfood_amt = 0 - */ - var/list/carrying = list() // List of things on the tray. - Doohl - var/max_carry = 10 // w_class = 1 -- takes up 1 - // w_class = 2 -- takes up 3 - // w_class = 3 -- takes up 5 - -/obj/item/weapon/tray/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) - - // Drop all the things. All of them. - overlays.Cut() - for(var/obj/item/I in carrying) - I.loc = M.loc - carrying.Remove(I) - if(isturf(I.loc)) - spawn() - for(var/i = 1, i <= rand(1,2), i++) - if(I) - step(I, pick(NORTH,SOUTH,EAST,WEST)) - sleep(rand(2,4)) - - - if((M_CLUMSY in user.mutations) && prob(50)) //What if he's a clown? - M << "\red You accidentally slam yourself with the [src]!" - M.Weaken(1) - user.take_organ_damage(2) - if(prob(50)) - playsound(M, 'sound/items/trayhit1.ogg', 50, 1) - return - else - playsound(M, 'sound/items/trayhit2.ogg', 50, 1) //sound playin' - return //it always returns, but I feel like adding an extra return just for safety's sakes. EDIT; Oh well I won't :3 - - var/mob/living/carbon/human/H = M ///////////////////////////////////// /Let's have this ready for later. - - - if(!(user.zone_sel.selecting == ("eyes" || "head"))) //////////////hitting anything else other than the eyes - if(prob(33)) - src.add_blood(H) - var/turf/location = H.loc - if (istype(location, /turf/simulated)) - location.add_blood(H) ///Plik plik, the sound of blood - - M.attack_log += text("\[[time_stamp()]\] Has been attacked with [src.name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to attack [M.name] ([M.ckey])") - msg_admin_attack("[user.name] ([user.ckey]) used the [src.name] to attack [M.name] ([M.ckey]) (JMP)") - - if(!iscarbon(user)) - M.LAssailant = null - else - M.LAssailant = user - - if(prob(15)) - M.Weaken(3) - M.take_organ_damage(3) - else - M.take_organ_damage(5) - if(prob(50)) - playsound(M, 'sound/items/trayhit1.ogg', 50, 1) - for(var/mob/O in viewers(M, null)) - O.show_message(text("\red [] slams [] with the tray!", user, M), 1) - return - else - playsound(M, 'sound/items/trayhit2.ogg', 50, 1) //we applied the damage, we played the sound, we showed the appropriate messages. Time to return and stop the proc - for(var/mob/O in viewers(M, null)) - O.show_message(text("\red [] slams [] with the tray!", user, M), 1) - return - - - - - if(istype(M, /mob/living/carbon/human) && ((H.head && H.head.flags & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || (H.glasses && H.glasses.flags & GLASSESCOVERSEYES))) - M << "\red You get slammed in the face with the tray, against your mask!" - if(prob(33)) - src.add_blood(H) - if (H.wear_mask) - H.wear_mask.add_blood(H) - if (H.head) - H.head.add_blood(H) - if (H.glasses && prob(33)) - H.glasses.add_blood(H) - var/turf/location = H.loc - if (istype(location, /turf/simulated)) //Addin' blood! At least on the floor and item :v - location.add_blood(H) - - if(prob(50)) - playsound(M, 'sound/items/trayhit1.ogg', 50, 1) - for(var/mob/O in viewers(M, null)) - O.show_message(text("\red [] slams [] with the tray!", user, M), 1) - else - playsound(M, 'sound/items/trayhit2.ogg', 50, 1) //sound playin' - for(var/mob/O in viewers(M, null)) - O.show_message(text("\red [] slams [] with the tray!", user, M), 1) - if(prob(10)) - M.Stun(rand(1,3)) - M.take_organ_damage(3) - return - else - M.take_organ_damage(5) - return - - else //No eye or head protection, tough luck! - M << "\red You get slammed in the face with the tray!" - if(prob(33)) - src.add_blood(M) - var/turf/location = H.loc - if (istype(location, /turf/simulated)) - location.add_blood(H) - - if(prob(50)) - playsound(M, 'sound/items/trayhit1.ogg', 50, 1) - for(var/mob/O in viewers(M, null)) - O.show_message(text("\red [] slams [] in the face with the tray!", user, M), 1) - else - playsound(M, 'sound/items/trayhit2.ogg', 50, 1) //sound playin' again - for(var/mob/O in viewers(M, null)) - O.show_message(text("\red [] slams [] in the face with the tray!", user, M), 1) - if(prob(30)) - M.Stun(rand(2,4)) - M.take_organ_damage(4) - return - else - M.take_organ_damage(8) - if(prob(30)) - M.Weaken(2) - return - return - -/obj/item/weapon/tray/var/cooldown = 0 //shield bash cooldown. based on world.time - -/obj/item/weapon/tray/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W, /obj/item/weapon/kitchen/rollingpin)) - if(cooldown < world.time - 25) - user.visible_message("[user] bashes [src] with [W]!") - playsound(user.loc, 'sound/effects/shieldbash.ogg', 50, 1) - cooldown = world.time - else - ..() - -/* -===============~~~~~================================~~~~~==================== -= = -= Code for trays carrying things. By Doohl for Doohl erryday Doohl Doohl~ = -= = -===============~~~~~================================~~~~~==================== -*/ -/obj/item/weapon/tray/proc/calc_carry() - // calculate the weight of the items on the tray - var/val = 0 // value to return - - for(var/obj/item/I in carrying) - if(I.w_class == 1.0) - val ++ - else if(I.w_class == 2.0) - val += 3 - else - val += 5 - - return val - -/obj/item/weapon/tray/pickup(mob/user) - - if(!isturf(loc)) - return - - for(var/obj/item/I in loc) - if( I != src && !I.anchored && !istype(I, /obj/item/clothing/under) && !istype(I, /obj/item/clothing/suit) && !istype(I, /obj/item/projectile) ) - var/add = 0 - if(I.w_class == 1.0) - add = 1 - else if(I.w_class == 2.0) - add = 3 - else - add = 5 - if(calc_carry() + add >= max_carry) - break - - I.loc = src - carrying.Add(I) - overlays += image("icon" = I.icon, "icon_state" = I.icon_state, "layer" = 30 + I.layer) - -/obj/item/weapon/tray/dropped(mob/user) - - var/mob/living/M - for(M in src.loc) //to handle hand switching - return - - var/foundtable = 0 - for(var/obj/structure/table/T in loc) - foundtable = 1 - break - - overlays.Cut() - - for(var/obj/item/I in carrying) - I.loc = loc - carrying.Remove(I) - if(!foundtable && isturf(loc)) - // if no table, presume that the person just shittily dropped the tray on the ground and made a mess everywhere! - spawn() - for(var/i = 1, i <= rand(1,2), i++) - if(I) - step(I, pick(NORTH,SOUTH,EAST,WEST)) - sleep(rand(2,4)) +/* Trays moved to /obj/item/weapon/storage/bag */ \ No newline at end of file diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm index 699cada546e..3e3b67fe6af 100644 --- a/code/game/objects/items/weapons/manuals.dm +++ b/code/game/objects/items/weapons/manuals.dm @@ -673,7 +673,7 @@ - + diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index e98c641c363..27f233e75b3 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -18,7 +18,7 @@ throw_range = 5 w_class = 3.0 hitsound = "swing_hit" - flags = FPRINT | CONDUCT | NOSHIELD | TABLEPASS + flags = CONDUCT | NOSHIELD origin_tech = "combat=3" attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut") sharp = 1 @@ -43,18 +43,18 @@ throw_range = 5 w_class = 2.0 hitsound = "swing_hit" - flags = FPRINT | TABLEPASS | NOSHIELD + flags = NOSHIELD origin_tech = "magnets=3;syndicate=4" attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") sharp = 1 edge = 1 /obj/item/weapon/melee/energy/sword/cyborg - var/hitcost = 500 + var/hitcost = 250 /obj/item/weapon/melee/energy/sword/cyborg/attack(mob/M, var/mob/living/silicon/robot/R) if(R.cell) - var/obj/item/weapon/cell/C = R.cell + var/obj/item/weapon/stock_parts/cell/C = R.cell if(active && !(C.use(hitcost))) attack_self() R << "It's out of charge!" @@ -79,6 +79,6 @@ throw_speed = 1 throw_range = 1 w_class = 4.0//So you can't hide it in your pocket or some such. - flags = FPRINT | TABLEPASS | NOSHIELD + flags = NOSHIELD attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") var/datum/effect/effect/system/spark_spread/spark_system diff --git a/code/game/objects/items/weapons/melee/misc.dm b/code/game/objects/items/weapons/melee/misc.dm index 6b80edd6fd0..e63dde9b9aa 100644 --- a/code/game/objects/items/weapons/melee/misc.dm +++ b/code/game/objects/items/weapons/melee/misc.dm @@ -3,7 +3,7 @@ desc = "A tool used by great men to placate the frothing masses." icon_state = "chain" item_state = "chain" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT force = 10 throwforce = 7 diff --git a/code/game/objects/items/weapons/mop.dm b/code/game/objects/items/weapons/mop.dm index b1c37f7cc47..5581eaf3bd5 100644 --- a/code/game/objects/items/weapons/mop.dm +++ b/code/game/objects/items/weapons/mop.dm @@ -8,7 +8,6 @@ throw_speed = 3 throw_range = 7 w_class = 3.0 - flags = FPRINT | TABLEPASS attack_verb = list("mopped", "bashed", "bludgeoned", "whacked") var/mopping = 0 var/mopcount = 0 @@ -50,7 +49,7 @@ user << "You have finished mopping!" -/obj/effect/attackby(obj/item/I, mob/user) +/obj/effect/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/weapon/mop) || istype(I, /obj/item/weapon/soap)) return ..() diff --git a/code/game/objects/items/weapons/ninja_manuscript.dm b/code/game/objects/items/weapons/ninja_manuscript.dm index 8c8674a42c7..75c07a2c3f5 100644 --- a/code/game/objects/items/weapons/ninja_manuscript.dm +++ b/code/game/objects/items/weapons/ninja_manuscript.dm @@ -6,7 +6,6 @@ throw_speed = 1 throw_range = 5 w_class = 3 - flags = TABLEPASS attack_verb = list("bashed", "whacked", "educated") var/charges = 1 diff --git a/code/game/objects/items/weapons/paint.dm b/code/game/objects/items/weapons/paint.dm index 9802b76018d..d35714f2111 100644 --- a/code/game/objects/items/weapons/paint.dm +++ b/code/game/objects/items/weapons/paint.dm @@ -14,7 +14,7 @@ var/global/list/cached_icons = list() amount_per_transfer_from_this = 10 possible_transfer_amounts = list(10,20,30,50,70) volume = 70 - flags = FPRINT | OPENCONTAINER + flags = OPENCONTAINER var/paint_type = "" afterattack(turf/simulated/target, mob/user, proximity) diff --git a/code/game/objects/items/weapons/power_cells.dm b/code/game/objects/items/weapons/power_cells.dm index cf9abda162f..7424f685ef8 100644 --- a/code/game/objects/items/weapons/power_cells.dm +++ b/code/game/objects/items/weapons/power_cells.dm @@ -1,11 +1,10 @@ -/obj/item/weapon/cell +/obj/item/weapon/stock_parts/cell name = "power cell" desc = "A rechargable electrochemical power cell." icon = 'icons/obj/power.dmi' icon_state = "cell" item_state = "cell" origin_tech = "powerstorage=1" - flags = FPRINT|TABLEPASS force = 5.0 throwforce = 5.0 throw_speed = 3 @@ -13,7 +12,7 @@ w_class = 3.0 var/charge = 0 // note %age conveted to actual charge in New var/maxcharge = 10000 - var/rating = 1 + rating = 1 m_amt = 700 g_amt = 50 var/rigged = 0 // true if rigged to explode @@ -25,7 +24,7 @@ viewers(user) << "[user] is licking the electrodes of the [src.name]! It looks like \he's trying to commit suicide." return (FIRELOSS) -/obj/item/weapon/cell/crap +/obj/item/weapon/stock_parts/cell/crap name = "\improper Nanotrasen brand rechargable AA battery" desc = "You can't top the plasma top." //TOTALLY TRADEMARK INFRINGEMENT origin_tech = "powerstorage=0" @@ -33,22 +32,22 @@ rating = 2 g_amt = 40 -/obj/item/weapon/cell/crap/empty/New() +/obj/item/weapon/stock_parts/cell/crap/empty/New() ..() charge = 0 -/obj/item/weapon/cell/secborg +/obj/item/weapon/stock_parts/cell/secborg name = "\improper Security borg rechargable D battery" origin_tech = "powerstorage=0" maxcharge = 6000 //6000 max charge / 1000 charge per shot = six shots rating = 2.5 g_amt = 40 -/obj/item/weapon/cell/secborg/empty/New() +/obj/item/weapon/stock_parts/cell/secborg/empty/New() ..() charge = 0 -/obj/item/weapon/cell/high +/obj/item/weapon/stock_parts/cell/high name = "high-capacity power cell" origin_tech = "powerstorage=2" icon_state = "hcell" @@ -56,11 +55,11 @@ rating = 3 g_amt = 60 -/obj/item/weapon/cell/high/empty/New() +/obj/item/weapon/stock_parts/cell/high/empty/New() ..() charge = 0 -/obj/item/weapon/cell/super +/obj/item/weapon/stock_parts/cell/super name = "super-capacity power cell" origin_tech = "powerstorage=5" icon_state = "scell" @@ -69,11 +68,11 @@ rating = 4 construction_cost = list("metal"=750,"glass"=100) -/obj/item/weapon/cell/super/empty/New() +/obj/item/weapon/stock_parts/cell/super/empty/New() ..() charge = 0 -/obj/item/weapon/cell/hyper +/obj/item/weapon/stock_parts/cell/hyper name = "hyper-capacity power cell" origin_tech = "powerstorage=6" icon_state = "hpcell" @@ -82,11 +81,11 @@ g_amt = 80 construction_cost = list("metal"=500,"glass"=150,"gold"=200,"silver"=200) -/obj/item/weapon/cell/hyper/empty/New() +/obj/item/weapon/stock_parts/cell/hyper/empty/New() ..() charge = 0 -/obj/item/weapon/cell/infinite +/obj/item/weapon/stock_parts/cell/infinite name = "infinite-capacity power cell!" icon_state = "icell" origin_tech = null @@ -96,7 +95,7 @@ use() return 1 -/obj/item/weapon/cell/potato +/obj/item/weapon/stock_parts/cell/potato name = "potato battery" desc = "A rechargable starch based power cell." origin_tech = "powerstorage=1" @@ -110,7 +109,7 @@ minor_fault = 1 -/obj/item/weapon/cell/slime +/obj/item/weapon/stock_parts/cell/slime name = "charged slime core" desc = "A yellow slime core infused with plasma, it crackles with power." origin_tech = "powerstorage=2;biotech=4" @@ -120,3 +119,27 @@ rating = 3 m_amt = 0 g_amt = 0 + +/obj/item/weapon/stock_parts/cell/pulse/carbine + name = "pulse carbine power cell" + maxcharge = 4000 + +/obj/item/weapon/stock_parts/cell/pulse/pistol + name = "pulse pistol power cell" + maxcharge = 1600 + +/obj/item/weapon/stock_parts/cell/emproof + name = "\improper EMP-proof cell" + desc = "An EMP-proof cell." + maxcharge = 5000 + rating = 2 + +/obj/item/weapon/stock_parts/cell/emproof/empty/New() + ..() + charge = 0 + +/obj/item/weapon/stock_parts/cell/emproof/emp_act(severity) + return + +/obj/item/weapon/stock_parts/cell/emproof/corrupt() + return diff --git a/code/game/objects/items/weapons/scrolls.dm b/code/game/objects/items/weapons/scrolls.dm index 6ca0f327e20..e7a9272aa6d 100644 --- a/code/game/objects/items/weapons/scrolls.dm +++ b/code/game/objects/items/weapons/scrolls.dm @@ -4,7 +4,6 @@ icon = 'icons/obj/wizard.dmi' icon_state = "scroll" var/uses = 4.0 - flags = FPRINT | TABLEPASS w_class = 2.0 item_state = "paper" throw_speed = 4 diff --git a/code/game/objects/items/weapons/shards.dm b/code/game/objects/items/weapons/shards.dm index cafcb4c3a44..ed1535eb4d9 100644 --- a/code/game/objects/items/weapons/shards.dm +++ b/code/game/objects/items/weapons/shards.dm @@ -7,33 +7,19 @@ sharp = 1 edge = 1 desc = "Could probably be used as ... a throwing weapon?" - w_class = 2.0 + w_class = 1.0 force = 5.0 - throwforce = 8.0 + throwforce = 10.0 item_state = "shard-glass" -// matter = list("glass" = 3750) + g_amt = MINERAL_MATERIAL_AMOUNT attack_verb = list("stabbed", "slashed", "sliced", "cut") + hitsound = 'sound/weapons/bladeslice.ogg' /obj/item/weapon/shard/suicide_act(mob/user) viewers(user) << pick("\red [user] is slitting \his wrists with \the [src]! It looks like \he's trying to commit suicide.", \ "\red [user] is slitting \his throat with \the [src]! It looks like \he's trying to commit suicide.") return (BRUTELOSS) -/obj/item/weapon/shard/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) - playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1) - return ..() - -/obj/item/weapon/shard/Bump() - - spawn( 0 ) - if (prob(20)) - src.force = 15 - else - src.force = 4 - ..() - return - return - /obj/item/weapon/shard/New() src.icon_state = pick("large", "medium", "small") @@ -50,23 +36,20 @@ else return -/obj/item/weapon/shard/attackby(obj/item/weapon/W as obj, mob/user as mob) - ..() - if ( istype(W, /obj/item/weapon/weldingtool)) - var/obj/item/weapon/weldingtool/WT = W +/obj/item/weapon/shard/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/weapon/weldingtool)) + var/obj/item/weapon/weldingtool/WT = I if(WT.remove_fuel(0, user)) var/obj/item/stack/sheet/glass/NG = new (user.loc) - for (var/obj/item/stack/sheet/glass/G in user.loc) - if(G==NG) + for(var/obj/item/stack/sheet/glass/G in user.loc) + if(G == NG) continue - if(G.amount>=G.max_amount) + if(G.amount >= G.max_amount) continue G.attackby(NG, user) - usr << "You add the newly-formed glass to the stack. It now contains [NG.amount] sheets." - //SN src = null - del(src) - return - return ..() + user << "You add the newly-formed glass to the stack. It now contains [NG.amount] sheet\s." + qdel(src) + ..() /obj/item/weapon/shard/Crossed(AM as mob|obj) if(ismob(AM)) diff --git a/code/game/objects/items/weapons/shields.dm b/code/game/objects/items/weapons/shields.dm index 774f097ca5f..760e0633f56 100644 --- a/code/game/objects/items/weapons/shields.dm +++ b/code/game/objects/items/weapons/shields.dm @@ -6,30 +6,29 @@ desc = "A shield adept at blocking blunt objects from connecting with the torso of the shield wielder." icon = 'icons/obj/weapons.dmi' icon_state = "riot" - flags = FPRINT | TABLEPASS| CONDUCT slot_flags = SLOT_BACK - force = 5.0 - throwforce = 5.0 - throw_speed = 1 - throw_range = 4 - w_class = 4.0 + force = 8 + throwforce = 5 + throw_speed = 2 + throw_range = 3 + w_class = 4 g_amt = 7500 m_amt = 1000 origin_tech = "materials=2" attack_verb = list("shoved", "bashed") var/cooldown = 0 //shield bash cooldown. based on world.time - IsShield() - return 1 +/obj/item/weapon/shield/riot/IsShield() + return 1 - attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W, /obj/item/weapon/melee/baton)) - if(cooldown < world.time - 25) - user.visible_message("[user] bashes [src] with [W]!") - playsound(user.loc, 'sound/effects/shieldbash.ogg', 50, 1) - cooldown = world.time - else - ..() +/obj/item/weapon/shield/riot/attackby(obj/item/weapon/W as obj, mob/user as mob, params) + if(istype(W, /obj/item/weapon/melee/baton)) + if(cooldown < world.time - 25) + user.visible_message("[user] bashes [src] with [W]!") + playsound(user.loc, 'sound/effects/shieldbash.ogg', 50, 1) + cooldown = world.time + else + ..() /obj/item/weapon/shield/riot/roman name = "roman shield" @@ -42,23 +41,100 @@ desc = "A shield capable of stopping most melee attacks. Protects user from almost all energy projectiles. It can be retracted, expanded, and stored anywhere." icon = 'icons/obj/weapons.dmi' icon_state = "eshield0" // eshield1 for expanded - flags = FPRINT | TABLEPASS| CONDUCT - force = 3.0 - throwforce = 5.0 - throw_speed = 1 - throw_range = 4 + force = 3 + throwforce = 3 + throw_speed = 3 + throw_range = 5 w_class = 1 origin_tech = "materials=4;magnets=3;syndicate=4" attack_verb = list("shoved", "bashed") var/active = 0 +/obj/item/weapon/shield/energy/IsShield() + return (active) + +/obj/item/weapon/shield/energy/IsReflect() + return (active) + +/obj/item/weapon/shield/energy/attack_self(mob/living/carbon/human/user) + if(user.disabilities & CLUMSY && prob(50)) + user << "You beat yourself in the head with [src]." + user.take_organ_damage(5) + active = !active + icon_state = "eshield[active]" + + if(active) + force = 10 + throwforce = 8 + throw_speed = 2 + w_class = 4 + playsound(user, 'sound/weapons/saberon.ogg', 35, 1) + user << "[src] is now active." + else + force = 3 + throwforce = 3 + throw_speed = 3 + w_class = 1 + playsound(user, 'sound/weapons/saberoff.ogg', 35, 1) + user << "[src] can now be concealed." + if(istype(user,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = user + H.update_inv_l_hand() + H.update_inv_r_hand() + add_fingerprint(user) + return + +/obj/item/weapon/shield/riot/tele + name = "telescopic shield" + desc = "An advanced riot shield made of lightweight materials that collapses for easy storage." + icon = 'icons/obj/weapons.dmi' + icon_state = "teleriot0" + icon_override = 'icons/mob/in-hand/tools.dmi' + slot_flags = null + force = 3 + throwforce = 3 + throw_speed = 3 + throw_range = 4 + w_class = 3 + var/active = 0 + +/obj/item/weapon/shield/riot/tele/IsShield() + return (active) + +/obj/item/weapon/shield/riot/tele/attack_self(mob/living/user) + active = !active + icon_state = "teleriot[active]" + playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, 1) + + if(active) + force = 8 + throwforce = 5 + throw_speed = 2 + w_class = 4 + slot_flags = SLOT_BACK + user << "You extend \the [src]." + else + force = 3 + throwforce = 3 + throw_speed = 3 + w_class = 3 + slot_flags = null + user << "[src] can now be concealed." + if(istype(user,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = user + H.update_inv_l_hand() + H.update_inv_r_hand() + add_fingerprint(user) + return + + /obj/item/weapon/cloaking_device name = "cloaking device" desc = "Use this to become invisible to the human eyesocket." icon = 'icons/obj/device.dmi' icon_state = "shield0" var/active = 0.0 - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT item_state = "electronic" throwforce = 10.0 throw_speed = 2 diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 25cb47ef3e8..45bb865df0f 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -9,12 +9,11 @@ icon_state = "backpack" item_state = "backpack" w_class = 4.0 - flags = FPRINT|TABLEPASS slot_flags = SLOT_BACK //ERROOOOO max_w_class = 3 max_combined_w_class = 21 -/obj/item/weapon/storage/backpack/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/storage/backpack/attackby(obj/item/weapon/W as obj, mob/user as mob, params) playsound(src.loc, "rustle", 50, 1, -5) ..() @@ -34,7 +33,7 @@ ..() return - attackby(obj/item/weapon/W as obj, mob/user as mob) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(crit_fail) user << "\red The Bluespace generator isn't working." return @@ -84,6 +83,12 @@ icon_state = "clownpack" item_state = "clownpack" +/obj/item/weapon/storage/backpack/mime + name = "Parcel Parceaux" + desc = "A silent backpack made for those silent workers. Silence Co." + icon_state = "mimepack" + item_state = "mimepack" + /obj/item/weapon/storage/backpack/medic name = "medical backpack" desc = "It's a backpack especially designed for use in a sterile environment." diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm index 3fa71922efd..ff1b025a2ee 100644 --- a/code/game/objects/items/weapons/storage/bags.dm +++ b/code/game/objects/items/weapons/storage/bags.dm @@ -10,6 +10,7 @@ * Plant Bag * Sheet Snatcher * Book Bag + * Tray * * -Sayu */ @@ -21,7 +22,6 @@ display_contents_with_number = 0 // UNStABLE AS FuCK, turn on when it stops crashing clients use_to_pickup = 1 slot_flags = SLOT_BELT - flags = FPRINT | TABLEPASS // ----------------------------- // Trash bag @@ -38,6 +38,11 @@ storage_slots = 30 can_hold = list() // any cant_hold = list("/obj/item/weapon/disk/nuclear","/obj/item/flag/nation") + +/obj/item/weapon/storage/bag/trash/suicide_act(mob/user) + user.visible_message("[user] puts the [src.name] over their head and starts chomping at the insides! Disgusting!") + playsound(loc, 'sound/items/eatfood.ogg', 50, 1, -1) + return (TOXLOSS) /obj/item/weapon/storage/bag/trash/update_icon() if(contents.len == 0) @@ -48,10 +53,15 @@ icon_state = "trashbag2" else icon_state = "trashbag3" +/obj/item/weapon/storage/bag/trash/cyborg + /obj/item/weapon/storage/bag/trash/proc/janicart_insert(mob/user, obj/structure/janitorialcart/J) J.put_in_cart(src, user) J.mybag=src J.update_icon() + +/obj/item/weapon/storage/bag/trash/cyborg/janicart_insert(mob/user, obj/structure/janitorialcart/J) + return // ----------------------------- @@ -209,7 +219,7 @@ break if(!inserted || !S.amount) - usr.u_equip(S) + usr.unEquip(S) usr.update_icons() //update our overlays if (usr.client && usr.s_active != src) usr.client.screen -= S @@ -308,7 +318,7 @@ w_class = 1 can_hold = list("/obj/item/weapon/coin","/obj/item/weapon/spacecash") - + // ----------------------------- // Book bag // ----------------------------- @@ -324,3 +334,96 @@ max_w_class = 3 w_class = 4 //Bigger than a book because physics can_hold = list(/obj/item/weapon/book, /obj/item/weapon/spellbook) //No bibles, consistent with bookcase + +/* + * Trays - Agouri + */ +/obj/item/weapon/storage/bag/tray + name = "tray" + icon = 'icons/obj/food.dmi' + icon_state = "tray" + desc = "A metal tray to lay food on." + force = 5 + throwforce = 10.0 + throw_speed = 3 + throw_range = 5 + w_class = 4.0 + flags = CONDUCT + m_amt = 3000 + +/obj/item/weapon/storage/bag/tray/attack(mob/living/M as mob, mob/living/user as mob) + ..() + // Drop all the things. All of them. + var/list/obj/item/oldContents = contents.Copy() + quick_empty() + + // Make each item scatter a bit + for(var/obj/item/I in oldContents) + spawn() + for(var/i = 1, i <= rand(1,2), i++) + if(I) + step(I, pick(NORTH,SOUTH,EAST,WEST)) + sleep(rand(2,4)) + + if(prob(50)) + playsound(M, 'sound/items/trayhit1.ogg', 50, 1) + else + playsound(M, 'sound/items/trayhit2.ogg', 50, 1) + + if(ishuman(M) || ismonkey(M)) + if(prob(10)) + M.Weaken(2) + +/obj/item/weapon/storage/bag/tray/proc/rebuild_overlays() + overlays.Cut() + for(var/obj/item/I in contents) + overlays += image("icon" = I.icon, "icon_state" = I.icon_state, "layer" = -1) + +/obj/item/weapon/storage/bag/tray/remove_from_storage(obj/item/W as obj, atom/new_location) + ..() + rebuild_overlays() + +/obj/item/weapon/storage/bag/tray/handle_item_insertion(obj/item/I, prevent_warning = 0) + overlays += image("icon" = I.icon, "icon_state" = I.icon_state, "layer" = -1) + ..() + +/obj/item/weapon/storage/bag/tray/cyborg + +/obj/item/weapon/storage/bag/tray/cyborg/afterattack(atom/target, mob/user as mob) + if ( isturf(target) || istype(target,/obj/structure/table) ) + var foundtable = istype(target,/obj/structure/table/) + if ( !foundtable ) //it must be a turf! + for(var/obj/structure/table/T in target) + foundtable = 1 + break + + var turf/dropspot + if ( !foundtable ) // don't unload things onto walls or other silly places. + dropspot = user.loc + else if ( isturf(target) ) // they clicked on a turf with a table in it + dropspot = target + else // they clicked on a table + dropspot = target.loc + + overlays = null + + var droppedSomething = 0 + + for(var/obj/item/I in contents) + I.loc = dropspot + contents.Remove(I) + droppedSomething = 1 + if(!foundtable && isturf(dropspot)) + // if no table, presume that the person just shittily dropped the tray on the ground and made a mess everywhere! + spawn() + for(var/i = 1, i <= rand(1,2), i++) + if(I) + step(I, pick(NORTH,SOUTH,EAST,WEST)) + sleep(rand(2,4)) + if ( droppedSomething ) + if ( foundtable ) + user.visible_message("\blue [user] unloads their service tray.") + else + user.visible_message("\blue [user] drops all the items on their tray.") + + return ..() diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index eb7bc3fb8d6..773525b4da7 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -4,7 +4,6 @@ icon = 'icons/obj/clothing/belts.dmi' icon_state = "utilitybelt" item_state = "utility" - flags = FPRINT | TABLEPASS slot_flags = SLOT_BELT attack_verb = list("whipped", "lashed", "disciplined") @@ -21,10 +20,10 @@ if (!M.restrained() && !M.stat && can_use()) switch(over_object.name) if("r_hand") - M.u_equip(src) + M.unEquip(src) M.put_in_r_hand(src) if("l_hand") - M.u_equip(src) + M.unEquip(src) M.put_in_l_hand(src) src.add_fingerprint(usr) return @@ -60,6 +59,9 @@ new /obj/item/weapon/wirecutters(src) new /obj/item/stack/cable_coil(src,30,pick("red","yellow","orange")) +/obj/item/weapon/storage/belt/utility/full/response_team/New() + ..() + new /obj/item/device/multitool(src) /obj/item/weapon/storage/belt/utility/atmostech/New() ..() @@ -95,7 +97,8 @@ "/obj/item/device/flashlight/pen", "/obj/item/clothing/mask/surgical", "/obj/item/clothing/gloves/color/latex", - "/obj/item/weapon/reagent_containers/hypospray/autoinjector" + "/obj/item/weapon/reagent_containers/hypospray/autoinjector", + "/obj/item/device/sensor_device" ) @@ -110,7 +113,7 @@ "/obj/item/weapon/grenade/flashbang", "/obj/item/weapon/grenade/chem_grenade/teargas", "/obj/item/weapon/reagent_containers/spray/pepper", - "/obj/item/weapon/handcuffs", + "/obj/item/weapon/restraints/handcuffs", "/obj/item/device/flash", "/obj/item/clothing/glasses", "/obj/item/ammo_casing/shotgun", @@ -128,6 +131,13 @@ ..() new /obj/item/device/flashlight/seclite(src) +/obj/item/weapon/storage/belt/security/response_team/New() + ..() + new /obj/item/weapon/grenade/flashbang(src) + new /obj/item/weapon/grenade/flashbang(src) + new /obj/item/weapon/melee/telebaton(src) + new /obj/item/weapon/restraints/handcuffs(src) + /obj/item/weapon/storage/belt/soulstone name = "soul stone belt" desc = "Designed for ease of access to the shards during a fight, as to not let a single enemy spirit slip away" @@ -291,7 +301,7 @@ name = "yellow fannypack" icon_state = "fannypack_yellow" item_state = "fannypack_yellow" - + // ------------------------------------- // Bluespace Belt // ------------------------------------- @@ -308,16 +318,6 @@ max_combined_w_class = 21 // = 14 * 1.5, not 14 * 2. This is deliberate origin_tech = "bluespace=4" can_hold = list() - New() - if(prob(5)) - //Sometimes people choose justice. - //Sometimes justice chooses you. - visible_message("That doesn't look like a normal Toolbelt of Holding...") - new /obj/item/weapon/storage/belt/bluespace/owlman(loc) - spawn(1) - del src - return - ..() proc/failcheck(mob/user as mob) if (prob(src.reliability)) return 1 //No failure @@ -413,7 +413,7 @@ new /obj/item/device/multitool(src) new /obj/item/stack/cable_coil(src) - new /obj/item/weapon/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) new /obj/item/weapon/dnainjector/xraymut(src) new /obj/item/weapon/dnainjector/firemut(src) new /obj/item/weapon/dnainjector/telemut(src) @@ -444,4 +444,3 @@ new /obj/item/device/analyzer(src) new /obj/item/device/healthanalyzer(src) - \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/bible.dm b/code/game/objects/items/weapons/storage/bible.dm index f521c369f88..20c336fa8a5 100644 --- a/code/game/objects/items/weapons/storage/bible.dm +++ b/code/game/objects/items/weapons/storage/bible.dm @@ -5,7 +5,6 @@ throw_speed = 1 throw_range = 5 w_class = 3.0 - flags = FPRINT | TABLEPASS var/mob/affecting = null var/deity_name = "Christ" @@ -67,7 +66,7 @@ user.take_organ_damage(0,10) return - if ((M_CLUMSY in user.mutations) && prob(50)) + if ((CLUMSY in user.mutations) && prob(50)) user << "\red The [src] slips out of your hand and hits your head." user.take_organ_damage(10) user.Paralyse(20) @@ -116,6 +115,6 @@ A.reagents.del_reagent("water") A.reagents.add_reagent("holywater",water2holy) -/obj/item/weapon/storage/bible/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/storage/bible/attackby(obj/item/weapon/W as obj, mob/user as mob, params) playsound(src.loc, "rustle", 50, 1, -5) ..() diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 628d287e7c5..db7ffa49f5a 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -41,22 +41,6 @@ autoignition_temperature = 530 // Kelvin - -/obj/item/weapon/storage/box/surveillance - name = "\improper DromedaryCo packet" - desc = "A packet of six imported DromedaryCo cancer sticks. A label on the packaging reads, \"Wouldn't a slow death make a change?\"" - icon = 'icons/obj/cigarettes.dmi' - icon_state = "Dpacket" - item_state = "Dpacket" - w_class = 1 - foldable = null - New() - ..() - contents = list() - sleep(1) - for(var/i = 1 to 5) - new /obj/item/device/camera_bug(src) - /obj/item/weapon/storage/box/survival New() ..() @@ -77,6 +61,17 @@ new /obj/item/weapon/reagent_containers/hypospray/autoinjector( src ) return +/obj/item/weapon/storage/box/response_team + New() + ..() + contents = list() + sleep(1) + new /obj/item/clothing/mask/breath( src ) + new /obj/item/weapon/tank/emergency_oxygen/double/full( src ) + new /obj/item/clothing/glasses/night( src ) + new /obj/item/weapon/kitchenknife/combat( src ) // SURVIVAL KNIFE, FOR CARVING A BOW OUT OF THE BONES OF ASSISTANTS AFTER YOU CRASH-LAND ON THE STATION. + new /obj/item/weapon/reagent_containers/hypospray/autoinjector( src ) + return /obj/item/weapon/storage/box/gloves name = "box of latex gloves" @@ -183,6 +178,20 @@ new /obj/item/weapon/grenade/flashbang(src) new /obj/item/weapon/grenade/flashbang(src) +/obj/item/weapon/storage/box/flashes + name = "box of flashbulbs" + desc = "WARNING: Flashes can cause serious eye damage, protective eyewear is required." + icon_state = "flashbang" + + New() + ..() + new /obj/item/device/flash(src) + new /obj/item/device/flash(src) + new /obj/item/device/flash(src) + new /obj/item/device/flash(src) + new /obj/item/device/flash(src) + new /obj/item/device/flash(src) + /obj/item/weapon/storage/box/teargas name = "box of tear gas grenades (WARNING)" desc = "WARNING: These devices are extremely dangerous and can cause blindness and skin irritation." @@ -242,6 +251,20 @@ new /obj/item/weapon/implanter(src) new /obj/item/weapon/implantpad(src) +/obj/item/weapon/storage/box/exileimp + name = "boxed exile implant kit" + desc = "Box of exile implants. It has a picture of a clown being booted through the Gateway." + icon_state = "implant" + + New() + ..() + new /obj/item/weapon/implantcase/exile(src) + new /obj/item/weapon/implantcase/exile(src) + new /obj/item/weapon/implantcase/exile(src) + new /obj/item/weapon/implantcase/exile(src) + new /obj/item/weapon/implantcase/exile(src) + new /obj/item/weapon/implanter(src) + /obj/item/weapon/storage/box/deathimp name = "death alarm implant kit" desc = "Box of life sign monitoring implants." @@ -423,7 +446,7 @@ new /obj/item/weapon/card/id/prisoner/seven(src) /obj/item/weapon/storage/box/seccarts - name = "Spare R.O.B.U.S.T. Cartridges" + name = "spare R.O.B.U.S.T. Cartridges" desc = "A box full of R.O.B.U.S.T. Cartridges, used by Security." icon_state = "pda" @@ -445,13 +468,28 @@ New() ..() - new /obj/item/weapon/handcuffs(src) - new /obj/item/weapon/handcuffs(src) - new /obj/item/weapon/handcuffs(src) - new /obj/item/weapon/handcuffs(src) - new /obj/item/weapon/handcuffs(src) - new /obj/item/weapon/handcuffs(src) - new /obj/item/weapon/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) + +/obj/item/weapon/storage/box/zipties + name = "box of spare zipties" + desc = "A box full of zipties." + icon_state = "handcuff" + + New() + ..() + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) /obj/item/weapon/storage/box/fakesyndiesuit name = "boxed space suit and helmet" @@ -512,7 +550,6 @@ item_state = "zippo" storage_slots = 10 w_class = 1 - flags = TABLEPASS slot_flags = SLOT_BELT New() @@ -520,7 +557,7 @@ for(var/i=1; i <= storage_slots; i++) new /obj/item/weapon/match(src) - attackby(obj/item/weapon/match/W as obj, mob/user as mob) + attackby(obj/item/weapon/match/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/match) && W.lit == 0) W.lit = 1 W.icon_state = "match_lit" diff --git a/code/game/objects/items/weapons/storage/briefcase.dm b/code/game/objects/items/weapons/storage/briefcase.dm index d6d288c5734..390f7632ca3 100644 --- a/code/game/objects/items/weapons/storage/briefcase.dm +++ b/code/game/objects/items/weapons/storage/briefcase.dm @@ -3,7 +3,7 @@ desc = "It's made of AUTHENTIC faux-leather and has a price-tag still attached. Its owner must be a real professional." icon_state = "briefcase" item_state = "briefcase" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT hitsound = "swing_hit" force = 8.0 throw_speed = 2 @@ -14,43 +14,4 @@ attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked") /obj/item/weapon/storage/briefcase/New() - ..() - -/obj/item/weapon/storage/briefcase/attack(mob/living/M as mob, mob/living/user as mob) - //..() - - if ((M_CLUMSY in user.mutations) && prob(50)) - user << "\red The [src] slips out of your hand and hits your head." - user.take_organ_damage(10) - user.Paralyse(2) - return - - - M.attack_log += text("\[[time_stamp()]\] Has been attacked with [src.name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to attack [M.name] ([M.ckey])") - msg_admin_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (?)") - - if(!iscarbon(user)) - M.LAssailant = null - else - M.LAssailant = user - - if (M.stat < 2 && M.health < 50 && prob(90)) - var/mob/H = M - // ******* Check - if ((istype(H, /mob/living/carbon/human) && istype(H, /obj/item/clothing/head) && H.flags & 8 && prob(80))) - M << "\red The helmet protects you from being hit hard in the head!" - return - var/time = rand(2, 6) - if (prob(75)) - M.Paralyse(time) - else - M.Stun(time) - if(M.stat != 2) M.stat = 1 - for(var/mob/O in viewers(M, null)) - O.show_message(text("\red [] has been knocked unconscious!", M), 1, "\red You hear someone fall.", 2) - else - M << text("\red [] tried to knock you unconcious!",user) - M.eye_blurry += 3 - - return + ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index 37735cab0d8..41f998e5d6f 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -88,7 +88,6 @@ item_state = "candlebox5" storage_slots = 5 throwforce = 2 - flags = TABLEPASS slot_flags = SLOT_BELT @@ -130,7 +129,7 @@ for(var/obj/item/toy/crayon/crayon in contents) overlays += image('icons/obj/crayons.dmi',crayon.colourName) -/obj/item/weapon/storage/fancy/crayons/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/weapon/storage/fancy/crayons/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W,/obj/item/toy/crayon)) switch(W:colourName) if("mime") @@ -152,7 +151,6 @@ item_state = "cigpacket" w_class = 1 throwforce = 2 - flags = TABLEPASS slot_flags = SLOT_BELT storage_slots = 6 can_hold = list("/obj/item/clothing/mask/cigarette") @@ -321,7 +319,7 @@ overlays += image(icon, src, "ledb") return -/obj/item/weapon/storage/lockbox/vials/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/storage/lockbox/vials/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() update_icon() diff --git a/code/game/objects/items/weapons/storage/firstaid.dm b/code/game/objects/items/weapons/storage/firstaid.dm index bf36677777a..0cb6ecb6727 100644 --- a/code/game/objects/items/weapons/storage/firstaid.dm +++ b/code/game/objects/items/weapons/storage/firstaid.dm @@ -12,7 +12,7 @@ name = "first-aid kit" desc = "It's an emergency medical kit for those serious boo-boos." icon_state = "firstaid" - icon_override = 'icons/mob/in-hand/medkits.dmi' + icon_override = 'icons/mob/in-hand/medkits.dmi' throw_speed = 2 throw_range = 8 var/empty = 0 @@ -121,8 +121,8 @@ /obj/item/weapon/storage/firstaid/tactical/New() ..() if (empty) return - new /obj/item/clothing/tie/stethoscope( src ) - new /obj/item/weapon/surgicaldrill(src) + new /obj/item/clothing/accessory/stethoscope( src ) + new /obj/item/weapon/defibrillator/compact/combat/loaded(src) new /obj/item/weapon/reagent_containers/hypospray/combat(src) new /obj/item/weapon/reagent_containers/pill/bicaridine(src) new /obj/item/weapon/reagent_containers/pill/dermaline(src) @@ -154,10 +154,10 @@ if ((!( M.restrained() ) && !( M.stat ) /*&& M.pocket == src*/)) switch(over_object.name) if("r_hand") - M.u_equip(src) + M.unEquip(src) M.put_in_r_hand(src) if("l_hand") - M.u_equip(src) + M.unEquip(src) M.put_in_l_hand(src) src.add_fingerprint(usr) return diff --git a/code/game/objects/items/weapons/storage/internal.dm b/code/game/objects/items/weapons/storage/internal.dm new file mode 100644 index 00000000000..44c8aaa5697 --- /dev/null +++ b/code/game/objects/items/weapons/storage/internal.dm @@ -0,0 +1,85 @@ +//A storage item intended to be used by other items to provide storage functionality. +//Types that use this should consider overriding emp_act() and hear_talk(), unless they shield their contents somehow. +/obj/item/weapon/storage/internal + var/obj/item/master_item + +/obj/item/weapon/storage/internal/New(obj/item/MI) + master_item = MI + loc = master_item + name = master_item.name + verbs -= /obj/item/verb/verb_pickup //make sure this is never picked up. + ..() + +/obj/item/weapon/storage/internal/attack_hand() + return //make sure this is never picked up + +/obj/item/weapon/storage/internal/mob_can_equip() + return 0 //make sure this is never picked up + +//Helper procs to cleanly implement internal storages - storage items that provide inventory slots for other items. +//These procs are completely optional, it is up to the master item to decide when it's storage get's opened by calling open() +//However they are helpful for allowing the master item to pretend it is a storage item itself. +//If you are using these you will probably want to override attackby() as well. +//See /obj/item/clothing/suit/storage for an example. + +//items that use internal storage have the option of calling this to emulate default storage MouseDrop behaviour. +//returns 1 if the master item's parent's MouseDrop() should be called, 0 otherwise. It's strange, but no other way of +//doing it without the ability to call another proc's parent, really. +/obj/item/weapon/storage/internal/proc/handle_mousedrop(mob/user as mob, obj/over_object as obj) + if (ishuman(user) || ismonkey(user)) //so monkeys can take off their backpacks -- Urist + + if (istype(user.loc,/obj/mecha)) // stops inventory actions in a mech + return 0 + + if(over_object == user && Adjacent(user)) // this must come before the screen objects only block + src.open(user) + return 0 + + if (!( istype(over_object, /obj/screen) )) + return 1 + + //makes sure master_item is equipped before putting it in hand, so that we can't drag it into our hand from miles away. + //there's got to be a better way of doing this... + if (!(master_item.loc == user) || (master_item.loc && master_item.loc.loc == user)) + return 0 + + if (!( user.restrained() ) && !( user.stat )) + switch(over_object.name) + if("r_hand") + user.unEquip(master_item) + user.put_in_r_hand(master_item) + if("l_hand") + user.unEquip(master_item) + user.put_in_l_hand(master_item) + master_item.add_fingerprint(user) + return 0 + return 0 + +//items that use internal storage have the option of calling this to emulate default storage attack_hand behaviour. +//returns 1 if the master item's parent's attack_hand() should be called, 0 otherwise. +//It's strange, but no other way of doing it without the ability to call another proc's parent, really. +/obj/item/weapon/storage/internal/proc/handle_attack_hand(mob/user as mob) + + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(H.l_store == master_item && !H.get_active_hand()) //Prevents opening if it's in a pocket. + H.put_in_hands(master_item) + H.l_store = null + return 0 + if(H.r_store == master_item && !H.get_active_hand()) + H.put_in_hands(master_item) + H.r_store = null + return 0 + + src.add_fingerprint(user) + if (master_item.loc == user) + src.open(user) + return 0 + + for(var/mob/M in range(1, master_item.loc)) + if (M.s_active == src) + src.close(M) + return 1 + +/obj/item/weapon/storage/internal/Adjacent(var/atom/neighbor) + return master_item.Adjacent(neighbor) diff --git a/code/game/objects/items/weapons/storage/lockbox.dm b/code/game/objects/items/weapons/storage/lockbox.dm index f42ea800745..85de627f0b8 100644 --- a/code/game/objects/items/weapons/storage/lockbox.dm +++ b/code/game/objects/items/weapons/storage/lockbox.dm @@ -17,7 +17,7 @@ var/icon_broken = "lockbox+b" - attackby(obj/item/weapon/W as obj, mob/user as mob) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/card/id)) if(src.broken) user << "\red It appears to be broken." @@ -104,12 +104,12 @@ New() ..() - new /obj/item/clothing/tie/medal/gold/heroism(src) - new /obj/item/clothing/tie/medal/silver/security(src) - new /obj/item/clothing/tie/medal/silver/valor(src) - new /obj/item/clothing/tie/medal/nobel_science(src) - new /obj/item/clothing/tie/medal/bronze_heart(src) - new /obj/item/clothing/tie/medal/conduct(src) - new /obj/item/clothing/tie/medal/conduct(src) - new /obj/item/clothing/tie/medal/conduct(src) - new /obj/item/clothing/tie/medal/gold/captain(src) + new /obj/item/clothing/accessory/medal/gold/heroism(src) + new /obj/item/clothing/accessory/medal/silver/security(src) + new /obj/item/clothing/accessory/medal/silver/valor(src) + new /obj/item/clothing/accessory/medal/nobel_science(src) + new /obj/item/clothing/accessory/medal/bronze_heart(src) + new /obj/item/clothing/accessory/medal/conduct(src) + new /obj/item/clothing/accessory/medal/conduct(src) + new /obj/item/clothing/accessory/medal/conduct(src) + new /obj/item/clothing/accessory/medal/gold/captain(src) diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm index 2a4d03b8f0a..a898fa55066 100644 --- a/code/game/objects/items/weapons/storage/secure.dm +++ b/code/game/objects/items/weapons/storage/secure.dm @@ -32,25 +32,10 @@ ..() usr << text("The service panel is [src.open ? "open" : "closed"].") - attackby(obj/item/weapon/W as obj, mob/user as mob) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(locked) - if ( (istype(W, /obj/item/weapon/card/emag)||istype(W, /obj/item/weapon/melee/energy/blade)) && (!src.emagged)) - emagged = 1 - src.overlays += image('icons/obj/storage.dmi', icon_sparking) - sleep(6) - src.overlays = null - overlays += image('icons/obj/storage.dmi', icon_locking) - locked = 0 - if(istype(W, /obj/item/weapon/melee/energy/blade)) - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, src.loc) - spark_system.start() - playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1) - playsound(src.loc, "sparks", 50, 1) - user << "You slice through the lock on [src]." - else - user << "You short out the lock on [src]." - return + if ((istype(W, /obj/item/weapon/melee/energy/blade)) && (!src.emagged)) + emag_act(user, W) if (istype(W, /obj/item/weapon/screwdriver)) if (do_after(user, 20)) @@ -80,6 +65,25 @@ // -> storage/attackby() what with handle insertion, etc ..() + emag_act(user as mob, weapon as obj) + if(!emagged) + emagged = 1 + src.overlays += image('icons/obj/storage.dmi', icon_sparking) + sleep(6) + src.overlays = null + overlays += image('icons/obj/storage.dmi', icon_locking) + locked = 0 + if(istype(weapon, /obj/item/weapon/melee/energy/blade)) + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, src.loc) + spark_system.start() + playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1) + playsound(src.loc, "sparks", 50, 1) + user << "You slice through the lock on [src]." + else + user << "You short out the lock on [src]." + return + MouseDrop(over_object, src_location, over_location) if (locked) @@ -146,7 +150,6 @@ icon_state = "secure" item_state = "sec-case" desc = "A large briefcase with a digital locking system." - flags = FPRINT | TABLEPASS force = 8.0 throw_speed = 1 throw_range = 4 @@ -174,42 +177,6 @@ src.add_fingerprint(user) return - //I consider this worthless but it isn't my code so whatever. Remove or uncomment. - /*attack(mob/M as mob, mob/living/user as mob) - if ((M_CLUMSY in user.mutations) && prob(50)) - user << "\red The [src] slips out of your hand and hits your head." - user.take_organ_damage(10) - user.Paralyse(2) - return - - M.attack_log += text("\[[time_stamp()]\] Has been attacked with [src.name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to attack [M.name] ([M.ckey])") - - log_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])") - - var/t = user:zone_sel.selecting - if (t == "head") - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if (H.stat < 2 && H.health < 50 && prob(90)) - // ******* Check - if (istype(H, /obj/item/clothing/head) && H.flags & 8 && prob(80)) - H << "\red The helmet protects you from being hit hard in the head!" - return - var/time = rand(2, 6) - if (prob(75)) - H.Paralyse(time) - else - H.Stun(time) - if(H.stat != 2) H.stat = 1 - for(var/mob/O in viewers(H, null)) - O.show_message(text("\red [] has been knocked unconscious!", H), 1, "\red You hear someone fall.", 2) - else - H << text("\red [] tried to knock you unconcious!",user) - H.eye_blurry += 3 - - return*/ - // ----------------------------- // Secure Safe // ----------------------------- @@ -221,7 +188,6 @@ icon_opened = "safe0" icon_locking = "safeb" icon_sparking = "safespark" - flags = FPRINT | TABLEPASS force = 8.0 w_class = 8.0 max_w_class = 8 diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index c9df562f289..b22b813d1c1 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -1,6 +1,6 @@ // To clarify: // For use_to_pickup and allow_quick_gather functionality, -// see item/attackby() (/game/objects/items.dm) +// see item/attackby() (/game/objects/items.dm, params) // Do not remove this functionality without good reason, cough reagent_containers cough. // -Sayu @@ -22,6 +22,7 @@ var/allow_quick_gather //Set this variable to allow the object to have the 'toggle mode' verb, which quickly collects all items from a tile. var/collection_mode = 1; //0 = pick one at a time, 1 = pick all on tile var/foldable = null // BubbleWrap - if set, can be folded (when empty) into a sheet of cardboard + var/use_sound = "rustle" //sound played when used. null for no sound. /obj/item/weapon/storage/MouseDrop(obj/over_object as obj) if (ishuman(usr) || ismonkey(usr)) //so monkeys can take off their backpacks -- Urist @@ -45,10 +46,12 @@ if (!( M.restrained() ) && !( M.stat )) switch(over_object.name) if("r_hand") - M.u_equip(src) + if(!M.unEquip(src)) + return M.put_in_r_hand(src) if("l_hand") - M.u_equip(src) + if(!M.unEquip(src)) + return M.put_in_l_hand(src) src.add_fingerprint(usr) return @@ -72,6 +75,8 @@ L += G.gift if (istype(G.gift, /obj/item/weapon/storage)) L += G.gift:return_inv() + for(var/obj/item/weapon/folder/F in src) + L += F.contents return L /obj/item/weapon/storage/proc/show_to(mob/user as mob) @@ -101,6 +106,15 @@ user.s_active = null return +/obj/item/weapon/storage/proc/open(mob/user as mob) + if (src.use_sound) + playsound(src.loc, src.use_sound, 50, 1, -5) + + orient2hud(user) + if (user.s_active) + user.s_active.close(user) + show_to(user) + /obj/item/weapon/storage/proc/close(mob/user as mob) src.hide_from(user) @@ -192,7 +206,7 @@ //This proc return 1 if the item can be picked up and 0 if it can't. //Set the stop_messages to stop it from printing messages /obj/item/weapon/storage/proc/can_be_inserted(obj/item/W as obj, stop_messages = 0) - if(!istype(W)) return //Not an item + if(!istype(W) || (W.flags & ABSTRACT)) return //Not an item if(src.loc == W) return 0 //Means the item is already in the storage item @@ -240,15 +254,21 @@ usr << "[src] cannot hold [W] as it's a storage item of the same size." return 0 //To prevent the stacking of same sized storage items. + if(W.flags & NODROP) //SHOULD be handled in unEquip, but better safe than sorry. + usr << "\the [W] is stuck to your hand, you can't put it in \the [src]" + return 0 + return 1 //This proc handles items being inserted. It does not perform any checks of whether an item can or can't be inserted. That's done by can_be_inserted() //The stop_warning parameter will stop the insertion message from being displayed. It is intended for cases where you are inserting multiple items at once, //such as when picking up all the items on a tile with one click. /obj/item/weapon/storage/proc/handle_item_insertion(obj/item/W as obj, prevent_warning = 0) - if(!istype(W)) return 0 + if(!istype(W)) + return 0 if(usr) - usr.u_equip(W) + if(!usr.unEquip(W)) + return 0 usr.update_icons() //update our overlays W.loc = src W.on_enter_storage(src) @@ -308,7 +328,7 @@ return 1 //This proc is called when you want to place an item into the storage item. -/obj/item/weapon/storage/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/weapon/storage/attackby(obj/item/W as obj, mob/user as mob, params) ..() if(isrobot(user)) @@ -318,19 +338,6 @@ if(!can_be_inserted(W)) return 0 - if(istype(W, /obj/item/weapon/tray)) - var/obj/item/weapon/tray/T = W - if(T.calc_carry() > 0) - if(prob(85)) - user << "\red The tray won't fit in [src]." - return 1 - else - W.loc = user.loc - if ((user.client && user.s_active != src)) - user.client.screen -= W - W.dropped(user) - user << "\red God damnit!" - handle_item_insertion(W) return 1 @@ -450,6 +457,39 @@ del(src) //BubbleWrap END +//Returns the storage depth of an atom. This is the number of storage items the atom is contained in before reaching toplevel (the area). +//Returns -1 if the atom was not found on container. +/atom/proc/storage_depth(atom/container) + var/depth = 0 + var/atom/cur_atom = src + while (cur_atom && !(cur_atom in container.contents)) + if (isarea(cur_atom)) + return -1 + if (istype(cur_atom.loc, /obj/item/weapon/storage)) + depth++ + cur_atom = cur_atom.loc + if (!cur_atom) + return -1 //inside something with a null loc. + + return depth + +//Like storage depth, but returns the depth to the nearest turf +//Returns -1 if no top level turf (a loc was null somewhere, or a non-turf atom's loc was an area somehow). +/atom/proc/storage_depth_turf() + var/depth = 0 + var/atom/cur_atom = src + + while (cur_atom && !isturf(cur_atom)) + if (isarea(cur_atom)) + return -1 + if (istype(cur_atom.loc, /obj/item/weapon/storage)) + depth++ + cur_atom = cur_atom.loc + + if (!cur_atom) + return -1 //inside something with a null loc. + + return depth diff --git a/code/game/objects/items/weapons/storage/toolbox.dm b/code/game/objects/items/weapons/storage/toolbox.dm index 4c7ea0617a0..cb04eeaccd3 100644 --- a/code/game/objects/items/weapons/storage/toolbox.dm +++ b/code/game/objects/items/weapons/storage/toolbox.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/storage.dmi' icon_state = "red" item_state = "toolbox_red" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT force = 10.0 throwforce = 10.0 throw_speed = 2 diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index 6b4fc5a43bd..710251b34d7 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -8,11 +8,12 @@ new /obj/item/weapon/card/id/syndicate(src) new /obj/item/weapon/card/id/syndicate(src) new /obj/item/clothing/shoes/syndigaloshes(src) + new /obj/item/device/camera_bug(src) return if("stealth") new /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow(src) - new /obj/item/weapon/pen/paralysis(src) + new /obj/item/weapon/pen/sleepy(src) new /obj/item/device/chameleon(src) return @@ -134,15 +135,6 @@ new /obj/item/clothing/head/helmet/space/syndicate/black/red(src) return -/obj/item/weapon/storage/box/syndie_kit/surveillance - name = "box (S)" - -/obj/item/weapon/storage/box/syndie_kit/surveillance/New() - ..() - new /obj/item/device/handtv(src) - new /obj/item/weapon/storage/box/surveillance(src) - return - /obj/item/weapon/storage/box/syndie_kit/conversion name = "box (CK)" diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index 2e9ed7b70c9..cb991abd057 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -4,7 +4,6 @@ icon_state = "stunbaton" item_state = "baton" slot_flags = SLOT_BELT - flags = FPRINT | TABLEPASS force = 10 throwforce = 7 w_class = 3 @@ -12,7 +11,7 @@ attack_verb = list("beaten") var/stunforce = 7 var/status = 0 - var/obj/item/weapon/cell/high/bcell = null + var/obj/item/weapon/stock_parts/cell/high/bcell = null var/hitcost = 1500 /obj/item/weapon/melee/baton/suicide_act(mob/user) @@ -25,7 +24,7 @@ return /obj/item/weapon/melee/baton/CheckParts() - bcell = locate(/obj/item/weapon/cell) in contents + bcell = locate(/obj/item/weapon/stock_parts/cell) in contents update_icon() /obj/item/weapon/melee/baton/loaded/New() //this one starts with a cell pre-installed. @@ -60,9 +59,9 @@ if(!bcell) user <<"The baton does not have a power source installed." -/obj/item/weapon/melee/baton/attackby(obj/item/weapon/W, mob/user) - if(istype(W, /obj/item/weapon/cell)) - var/obj/item/weapon/cell/C = W +/obj/item/weapon/melee/baton/attackby(obj/item/weapon/W, mob/user, params) + if(istype(W, /obj/item/weapon/stock_parts/cell)) + var/obj/item/weapon/stock_parts/cell/C = W if(bcell) user << "[src] already has a cell." else @@ -102,7 +101,7 @@ add_fingerprint(user) /obj/item/weapon/melee/baton/attack(mob/M, mob/living/user) - if(status && (M_CLUMSY in user.mutations) && prob(50)) + if(status && (CLUMSY in user.mutations) && prob(50)) user.visible_message("[user] accidentally hits themself with [src]!", \ "You accidentally hit yourself with [src]!") user.Weaken(stunforce*3) @@ -119,6 +118,7 @@ if(user.a_intent != "harm") if(status) + user.do_attack_animation(L) baton_stun(L, user) else L.visible_message("[L] has been prodded with [src] by [user]. Luckily it was off.", \ @@ -177,7 +177,7 @@ bcell = R.cell return ..() -/obj/item/weapon/melee/baton/robot/attackby(obj/item/weapon/W, mob/user) +/obj/item/weapon/melee/baton/robot/attackby(obj/item/weapon/W, mob/user, params) return /obj/item/weapon/melee/baton/loaded/ntcane diff --git a/code/game/objects/items/weapons/surgery_tools.dm b/code/game/objects/items/weapons/surgery_tools.dm index dab630f188a..2354dcb9832 100644 --- a/code/game/objects/items/weapons/surgery_tools.dm +++ b/code/game/objects/items/weapons/surgery_tools.dm @@ -16,9 +16,9 @@ desc = "Retracts stuff." icon = 'icons/obj/surgery.dmi' icon_state = "retractor" - m_amt = 10000 - g_amt = 5000 - flags = FPRINT | TABLEPASS | CONDUCT + m_amt = 6000 + g_amt = 3000 + flags = CONDUCT w_class = 2.0 origin_tech = "materials=1;biotech=1" @@ -132,7 +132,7 @@ LOOK FOR SURGERY.DM*/ icon_state = "hemostat" m_amt = 5000 g_amt = 2500 - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT w_class = 2.0 origin_tech = "materials=1;biotech=1" attack_verb = list("attacked", "pinched") @@ -265,9 +265,9 @@ LOOK FOR SURGERY.DM*/ desc = "This stops bleeding." icon = 'icons/obj/surgery.dmi' icon_state = "cautery" - m_amt = 5000 - g_amt = 2500 - flags = FPRINT | TABLEPASS | CONDUCT + m_amt = 2500 + g_amt = 750 + flags = CONDUCT w_class = 2.0 origin_tech = "materials=1;biotech=1" attack_verb = list("burnt") @@ -356,9 +356,9 @@ LOOK FOR SURGERY.DM*/ icon = 'icons/obj/surgery.dmi' icon_state = "drill" hitsound = 'sound/weapons/circsawhit.ogg' - m_amt = 15000 - g_amt = 10000 - flags = FPRINT | TABLEPASS | CONDUCT + m_amt = 10000 + g_amt = 6000 + flags = CONDUCT force = 15.0 w_class = 2.0 origin_tech = "materials=1;biotech=1" @@ -377,7 +377,7 @@ LOOK FOR SURGERY.DM*/ desc = "Cut, cut, and once more cut." icon = 'icons/obj/surgery.dmi' icon_state = "scalpel" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT force = 10.0 sharp = 1 edge = 1 @@ -385,8 +385,8 @@ LOOK FOR SURGERY.DM*/ throwforce = 5.0 throw_speed = 3 throw_range = 5 - m_amt = 10000 - g_amt = 5000 + m_amt = 4000 + g_amt = 1000 origin_tech = "materials=1;biotech=1" attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") @@ -401,9 +401,9 @@ LOOK FOR SURGERY.DM*/ if(!istype(M)) return ..() - //if(M.mutations & M_HUSK) return ..() + //if(M.mutations & HUSK) return ..() - if((M_CLUMSY in user.mutations) && prob(50)) + if((CLUMSY in user.mutations) && prob(50)) M = user return eyestab(M,user) @@ -631,14 +631,14 @@ LOOK FOR SURGERY.DM*/ icon = 'icons/obj/surgery.dmi' icon_state = "saw3" hitsound = 'sound/weapons/circsawhit.ogg' - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT force = 15.0 w_class = 2.0 throwforce = 9.0 throw_speed = 3 throw_range = 5 - m_amt = 20000 - g_amt = 10000 + m_amt = 10000 + g_amt = 6000 origin_tech = "materials=1;biotech=1" attack_verb = list("attacked", "slashed", "sawed", "cut") sharp = 1 @@ -649,7 +649,7 @@ LOOK FOR SURGERY.DM*/ if(!istype(M)) return ..() - if((M_CLUMSY in user.mutations) && prob(50)) + if((CLUMSY in user.mutations) && prob(50)) M = user return eyestab(M,user) diff --git a/code/game/objects/items/weapons/swords_axes_etc.dm b/code/game/objects/items/weapons/swords_axes_etc.dm index 375f07f05a6..41902f61084 100644 --- a/code/game/objects/items/weapons/swords_axes_etc.dm +++ b/code/game/objects/items/weapons/swords_axes_etc.dm @@ -27,7 +27,7 @@ blade_color = pick("red","blue","green","purple") /obj/item/weapon/melee/energy/sword/attack_self(mob/living/user as mob) - if ((M_CLUMSY in user.mutations) && prob(50)) + if ((CLUMSY in user.mutations) && prob(50)) user << "\red You accidentally cut yourself with [src]." user.take_organ_damage(5,5) active = !active @@ -60,7 +60,7 @@ add_fingerprint(user) return -/obj/item/weapon/melee/energy/sword/attackby(obj/item/weapon/W, mob/living/user) +/obj/item/weapon/melee/energy/sword/attackby(obj/item/weapon/W, mob/living/user, params) ..() if(istype(W, /obj/item/weapon/melee/energy/sword)) if(W == src) @@ -101,12 +101,11 @@ icon = 'icons/obj/weapons.dmi' icon_state = "baton" item_state = "classic_baton" - flags = FPRINT | TABLEPASS slot_flags = SLOT_BELT force = 10 /obj/item/weapon/melee/classic_baton/attack(mob/M as mob, mob/living/user as mob) - if ((M_CLUMSY in user.mutations) && prob(50)) + if ((CLUMSY in user.mutations) && prob(50)) user << "\red You club yourself over the head." user.Weaken(3 * force) if(ishuman(user)) @@ -125,7 +124,7 @@ if (user.a_intent == "harm") if(!..()) return playsound(get_turf(src), "swing_hit", 50, 1, -1) - if (M.stuttering < 8 && (!(M_HULK in M.mutations)) /*&& (!istype(H:wear_suit, /obj/item/clothing/suit/judgerobe))*/) + if (M.stuttering < 8 && (!(HULK in M.mutations)) /*&& (!istype(H:wear_suit, /obj/item/clothing/suit/judgerobe))*/) M.stuttering = 8 M.Stun(8) M.Weaken(8) @@ -157,7 +156,6 @@ icon = 'icons/obj/weapons.dmi' icon_state = "telebaton_0" item_state = "telebaton_0" - flags = FPRINT | TABLEPASS slot_flags = SLOT_BELT w_class = 2 force = 3 @@ -203,7 +201,7 @@ /obj/item/weapon/melee/telebaton/attack(mob/target as mob, mob/living/user as mob) if(on) add_fingerprint(user) - if((M_CLUMSY in user.mutations) && prob(50)) + if((CLUMSY in user.mutations) && prob(50)) user << "You club yourself over the head." user.Weaken(3 * force) if(ishuman(user)) @@ -284,40 +282,4 @@ src.w_class = 5 hitsound = "swing_hit" src.add_fingerprint(user) - return - - -/* - * Energy Shield - */ -/obj/item/weapon/shield/energy/IsShield() - if(active) - return 1 - else - return 0 - -/obj/item/weapon/shield/energy/attack_self(mob/living/user as mob) - if ((M_CLUMSY in user.mutations) && prob(50)) - user << "\red You beat yourself in the head with [src]." - user.take_organ_damage(5) - active = !active - if (active) - force = 10 - reflect_chance = 100 - icon_state = "eshield[active]" - w_class = 4 - playsound(user, 'sound/weapons/saberon.ogg', 50, 1) - user << "\blue [src] is now active." - else - force = 3 - icon_state = "eshield[active]" - w_class = 1 - reflect_chance = 0 - playsound(user, 'sound/weapons/saberoff.ogg', 50, 1) - user << "\blue [src] can now be concealed." - if(istype(user,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - H.update_inv_l_hand() - H.update_inv_r_hand() - add_fingerprint(user) - return + return \ No newline at end of file diff --git a/code/game/objects/items/weapons/table_rack_parts.dm b/code/game/objects/items/weapons/table_rack_parts.dm index 042efc84203..2c2b44ae387 100644 --- a/code/game/objects/items/weapons/table_rack_parts.dm +++ b/code/game/objects/items/weapons/table_rack_parts.dm @@ -11,7 +11,7 @@ /* * Table Parts */ -/obj/item/weapon/table_parts/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/table_parts/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if (istype(W, /obj/item/weapon/wrench)) new /obj/item/stack/sheet/metal( user.loc ) @@ -36,7 +36,7 @@ /* * Reinforced Table Parts */ -/obj/item/weapon/table_parts/reinforced/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/table_parts/reinforced/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/wrench)) new /obj/item/stack/sheet/metal( user.loc ) new /obj/item/stack/rods( user.loc ) @@ -51,7 +51,7 @@ /* * Wooden Table Parts */ -/obj/item/weapon/table_parts/wood/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/table_parts/wood/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/wrench)) new /obj/item/stack/sheet/wood( user.loc ) del(src) @@ -65,7 +65,7 @@ /* * Rack Parts */ -/obj/item/weapon/rack_parts/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/rack_parts/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if (istype(W, /obj/item/weapon/wrench)) new /obj/item/stack/sheet/metal( user.loc ) diff --git a/code/game/objects/items/weapons/tanks/tank_types.dm b/code/game/objects/items/weapons/tanks/tank_types.dm index b5fa8e36b95..7c39f530ace 100644 --- a/code/game/objects/items/weapons/tanks/tank_types.dm +++ b/code/game/objects/items/weapons/tanks/tank_types.dm @@ -98,7 +98,7 @@ name = "plasma tank" desc = "Contains dangerous plasma. Do not inhale. Warning: extremely flammable." icon_state = "plasma" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = null //they have no straps! @@ -110,7 +110,7 @@ src.air_contents.update_values() return -/obj/item/weapon/tank/plasma/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/tank/plasma/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if (istype(W, /obj/item/weapon/flamethrower)) @@ -118,7 +118,7 @@ if ((!F.status)||(F.ptank)) return src.master = F F.ptank = src - user.before_take_item(src) + user.unEquip(src) src.loc = F return @@ -140,7 +140,7 @@ name = "emergency oxygen tank" desc = "Used for emergencies. Contains very little oxygen, so try to conserve it until you actually need it." icon_state = "emergency" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT w_class = 2.0 force = 4.0 diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index d4a0cb0c972..9d1907df0e8 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -4,7 +4,7 @@ /obj/item/weapon/tank name = "tank" icon = 'icons/obj/tank.dmi' - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BACK hitsound = 'sound/weapons/smash.ogg' w_class = 3 @@ -78,7 +78,7 @@ del(src) -/obj/item/weapon/tank/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/tank/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() var/obj/icon = src diff --git a/code/game/objects/items/weapons/tanks/watertank.dm b/code/game/objects/items/weapons/tanks/watertank.dm index 85d4aeacb01..02e3ec5a543 100644 --- a/code/game/objects/items/weapons/tanks/watertank.dm +++ b/code/game/objects/items/weapons/tanks/watertank.dm @@ -2,13 +2,14 @@ /obj/item/weapon/watertank name = "backpack water tank" desc = "A S.U.N.S.H.I.N.E. brand watertank backpack with nozzle to water plants." - icon = 'icons/obj/hydroponics.dmi' + icon = 'icons/obj/watertank.dmi' icon_state = "waterbackpack" item_state = "waterbackpack" w_class = 4.0 slot_flags = SLOT_BACK slowdown = 1 action_button_name = "Toggle Mister" + icon_action_button = "action_waterbackpack" var/obj/item/weapon/noz var/on = 0 @@ -18,39 +19,34 @@ ..() create_reagents(volume) noz = make_noz() - return - -/obj/item/weapon/watertank/examine() - set src in usr - ..() - for(var/datum/reagent/R in reagents.reagent_list) - usr << "[round(R.volume)] units of [R.name] left." - return /obj/item/weapon/watertank/ui_action_click() - if (usr.get_item_by_slot(slot_back) == src) - toggle_mister() - else - usr << "The watertank needs to be on your back to use!" - return + toggle_mister() /obj/item/weapon/watertank/verb/toggle_mister() set name = "Toggle Mister" set category = "Object" + if (usr.get_item_by_slot(slot_back) != src) + usr << "The watertank needs to be on your back to use." + return + if(usr.stat || !usr.canmove || usr.restrained()) + return on = !on var/mob/living/carbon/human/user = usr if(on) + if(noz == null) + noz = make_noz() + //Detach the nozzle into the user's hands - var/list/L = list("left hand" = slot_l_hand,"right hand" = slot_r_hand) - if(!user.equip_in_one_of_slots(noz, L)) + if(!user.put_in_hands(noz)) on = 0 - user << "You need a free hand to hold the mister!" + user << "You need a free hand to hold the mister." return noz.loc = user else //Remove from their hands and put back "into" the tank - remove_noz(user) + remove_noz() return /obj/item/weapon/watertank/proc/make_noz() @@ -58,21 +54,52 @@ /obj/item/weapon/watertank/equipped(mob/user, slot) if (slot != slot_back) - remove_noz(user) + remove_noz() -/obj/item/weapon/watertank/proc/remove_noz(mob/user) - var/mob/living/carbon/human/M = user - if(noz in get_both_hands(M)) - M.u_equip(noz) +/obj/item/weapon/watertank/proc/remove_noz() + if(ismob(noz.loc)) + var/mob/M = noz.loc + M.unEquip(noz, 1) return /obj/item/weapon/watertank/Destroy() if (on) - var/M = get(noz, /mob) - remove_noz(M) + remove_noz() + qdel(noz) + noz = null ..() return +/obj/item/weapon/watertank/attack_hand(mob/user as mob) + if(src.loc == user) + ui_action_click() + return + ..() + +/obj/item/weapon/watertank/MouseDrop(obj/over_object) + if(ishuman(src.loc)) + var/mob/living/carbon/human/H = src.loc + switch(over_object.name) + if("r_hand") + if(H.r_hand) + return + if(!H.unEquip(src)) + return + H.put_in_r_hand(src) + if("l_hand") + if(H.l_hand) + return + if(!H.unEquip(src)) + return + H.put_in_l_hand(src) + return + +/obj/item/weapon/watertank/attackby(obj/item/W, mob/user, params) + if(W == noz) + remove_noz() + return + ..() + // This mister item is intended as an extension of the watertank and always attached to it. // Therefore, it's designed to be "locked" to the player's hands or extended back onto // the watertank backpack. Allowing it to be placed elsewhere or created without a parent @@ -80,13 +107,15 @@ /obj/item/weapon/reagent_containers/spray/mister name = "water mister" desc = "A mister nozzle attached to a water tank." - icon = 'icons/obj/hydroponics.dmi' + icon = 'icons/obj/watertank.dmi' icon_state = "mister" item_state = "mister" + icon_override = 'icons/mob/in-hand/tools.dmi' w_class = 4.0 amount_per_transfer_from_this = 50 possible_transfer_amounts = list(25,50,100) volume = 500 + flags = NODROP | OPENCONTAINER | NOBLUDGEON var/obj/item/weapon/watertank/tank @@ -99,7 +128,7 @@ return /obj/item/weapon/reagent_containers/spray/mister/dropped(mob/user as mob) - user << "The mister snaps back onto the watertank!" + user << "The mister snaps back onto the watertank." tank.on = 0 loc = tank @@ -108,12 +137,22 @@ /proc/check_tank_exists(parent_tank, var/mob/living/carbon/human/M, var/obj/O) if (!parent_tank || !istype(parent_tank, /obj/item/weapon/watertank)) //To avoid weird issues from admin spawns - M.u_equip(O) + M.unEquip(O) qdel(0) return 0 else return 1 +/obj/item/weapon/reagent_containers/spray/mister/Move() + ..() + if(loc != tank.loc) + loc = tank.loc + +/obj/item/weapon/reagent_containers/spray/mister/afterattack(obj/target, mob/user, proximity) + if(target.loc == loc || target == tank) //Safety check so you don't fill your mister with mutagen or something and then blast yourself in the face with it putting it away + return + ..() + //Janitor tank /obj/item/weapon/watertank/janitor name = "backpack water tank" @@ -123,13 +162,12 @@ /obj/item/weapon/watertank/janitor/New() ..() - reagents.add_reagent("cleaner", 250) - + reagents.add_reagent("cleaner", 500) /obj/item/weapon/reagent_containers/spray/mister/janitor name = "janitor spray nozzle" desc = "A janitorial spray nozzle attached to a watertank, designed to clean up large messes." - icon = 'icons/obj/hydroponics.dmi' + icon = 'icons/obj/watertank.dmi' icon_state = "misterjani" item_state = "misterjani" amount_per_transfer_from_this = 5 @@ -142,25 +180,46 @@ amount_per_transfer_from_this = (amount_per_transfer_from_this == 10 ? 5 : 10) user << "You [amount_per_transfer_from_this == 10 ? "remove" : "fix"] the nozzle. You'll now use [amount_per_transfer_from_this] units per spray." -//Atmos tank +//ATMOS FIRE FIGHTING BACKPACK + +#define EXTINGUISHER 0 +#define NANOFROST 1 +#define METAL_FOAM 2 + /obj/item/weapon/watertank/atmos - name = "backpack water tank" - desc = "A backpack watertank with fire extinguisher nozzle, intended to fight fires. Shouldn't toxins have one of these?" + name = "backpack firefighter tank" + desc = "A refridgerated and pressurized backpack tank with extinguisher nozzle, intended to fight fires. Swaps between extinguisher, nanofrost launcher, and metal foam dispenser for breaches. Nanofrost converts plasma in the air to nitrogen, but only if it is combusting at the time." icon_state = "waterbackpackatmos" item_state = "waterbackpackatmos" - volume = 100 + volume = 200 /obj/item/weapon/watertank/atmos/make_noz() return new /obj/item/weapon/extinguisher/mini/nozzle(src) +/obj/item/weapon/watertank/atmos/dropped(mob/user as mob) + icon_state = "waterbackpackatmos" + if(istype(noz, /obj/item/weapon/extinguisher/mini/nozzle)) + var/obj/item/weapon/extinguisher/mini/nozzle/N = noz + N.nozzle_mode = 0 + /obj/item/weapon/extinguisher/mini/nozzle - name = "fire extinguisher nozzle" - desc = "A fire extinguisher nozzle attached to a water tank." - icon = 'icons/obj/hydroponics.dmi' - icon_state = "misteratmos" - item_state = "misteratmos" + name = "extinguisher nozzle" + desc = "A heavy duty nozzle attached to a firefighter's backpack tank." + icon = 'icons/obj/watertank.dmi' + icon_state = "atmos_nozzle" + item_state = "nozzleatmos" + icon_override = 'icons/mob/in-hand/tools.dmi' safety = 0 + max_water = 200 + power = 8 + precision = 1 + cooling_power = 5 + w_class = 5 + flags = NODROP //Necessary to ensure that the nozzle and tank never seperate var/obj/item/weapon/watertank/tank + var/nozzle_mode = 0 + var/metal_synthesis_cooldown = 0 + var/nanofrost_cooldown = 0 /obj/item/weapon/extinguisher/mini/nozzle/New(parent_tank) if(check_tank_exists(parent_tank, src)) @@ -170,10 +229,174 @@ loc = tank return +/obj/item/weapon/extinguisher/mini/nozzle/Move() + ..() + if(tank && loc != tank.loc) + loc = tank + return + +/obj/item/weapon/extinguisher/mini/nozzle/attack_self(mob/user as mob) + switch(nozzle_mode) + if(EXTINGUISHER) + nozzle_mode = NANOFROST + tank.icon_state = "waterbackpackatmos_1" + user << "Swapped to nanofrost launcher" + return + if(NANOFROST) + nozzle_mode = METAL_FOAM + tank.icon_state = "waterbackpackatmos_2" + user << "Swapped to metal foam synthesizer" + return + if(METAL_FOAM) + nozzle_mode = EXTINGUISHER + tank.icon_state = "waterbackpackatmos_0" + user << "Swapped to water extinguisher" + return + return + /obj/item/weapon/extinguisher/mini/nozzle/dropped(mob/user as mob) - user << "The nozzle snaps back onto the watertank!" + user << "The nozzle snaps back onto the tank!" tank.on = 0 loc = tank -/obj/item/weapon/extinguisher/mini/nozzle/attack_self() +/obj/item/weapon/extinguisher/mini/nozzle/afterattack(atom/target, mob/user) + if(nozzle_mode == EXTINGUISHER) + ..() + return + var/Adj = user.Adjacent(target) + if(Adj) + AttemptRefill(target, user) + if(nozzle_mode == NANOFROST) + if(Adj) + return //Safety check so you don't blast yourself trying to refill your tank + var/datum/reagents/R = reagents + if(R.total_volume < 100) + user << "You need at least 100 units of water to use the nanofrost launcher!" + return + if(nanofrost_cooldown) + user << "Nanofrost launcher is still recharging" + return + nanofrost_cooldown = 1 + R.remove_any(100) + var/obj/effect/nanofrost_container/A = new /obj/effect/nanofrost_container(get_turf(src)) + log_game("[user.ckey] ([user.name]) used Nanofrost at [get_area(user)] ([user.x], [user.y], [user.z]).") + playsound(src,'sound/items/syringeproj.ogg',40,1) + for(var/a=0, a<5, a++) + step_towards(A, target) + sleep(2) + A.Smoke() + spawn(100) + if(src) + nanofrost_cooldown = 0 + return + if(nozzle_mode == METAL_FOAM) + if(!Adj|| !istype(target, /turf)) + return + if(metal_synthesis_cooldown < 5) + var/obj/effect/effect/foam/F = new /obj/effect/effect/foam(get_turf(target), 1) + F.amount = 0 + metal_synthesis_cooldown++ + spawn(100) + if(src) + metal_synthesis_cooldown-- + else + user << "Metal foam mix is still being synthesized." + return + +/obj/effect/nanofrost_container + name = "nanofrost container" + desc = "A frozen shell of ice containing nanofrost that freezes the surrounding area after activation." + icon = 'icons/effects/effects.dmi' + icon_state = "frozen_smoke_capsule" + mouse_opacity = 0 + pass_flags = PASSTABLE + +/obj/effect/nanofrost_container/proc/Smoke() + new /obj/effect/effect/freezing_smoke(src.loc, 6, 1) + var/obj/effect/decal/cleanable/flour/F = new /obj/effect/decal/cleanable/flour(src.loc) + F.color = "#B2FFFF" + F.name = "nanofrost residue" + F.desc = "Residue left behind from a nanofrost detonation. Perhaps there was a fire here?" + playsound(src,'sound/effects/bamf.ogg',100,1) + qdel(src) + +/obj/effect/effect/freezing_smoke + name = "nanofrost smoke" + icon_state = "smoke" + opacity = 0 + anchored = 0.0 + mouse_opacity = 0 + icon = 'icons/effects/96x96.dmi' + pixel_x = -32 + pixel_y = -32 + color = "#B2FFFF" + var/amount = 0 + +/obj/effect/effect/freezing_smoke/New(loc, var/amt, var/blast) + ..() + spawn(100+rand(10,30)) + delete() + amount = amt + if(amount) + var/datum/effect/effect/system/freezing_smoke_spread/F = new /datum/effect/effect/system/freezing_smoke_spread + F.set_up(amount, 0, src.loc) + F.start() + if(blast) + for(var/turf/T in trange(2, src.loc)) + Chilled(T) return + +/obj/effect/effect/freezing_smoke/proc/Chilled(atom/A) + if(istype(A, /turf/simulated)) + var/turf/simulated/T = A + if(T.air) + var/datum/gas_mixture/G = T.air + if(get_dist(T, src) < 2) // Otherwise we'll get silliness like people using Nanofrost to kill people through walls with cold air + G.temperature = 2 + update_nearby_tiles() + var/hotspot = (locate(/obj/fire) in T) + if(hotspot && !istype(T, /turf/space)) + var/CT = 10 + var/datum/gas_mixture/lowertemp = T.remove_air( T:air:total_moles() ) + lowertemp.temperature = max( min(lowertemp.temperature-(CT*1000),lowertemp.temperature / CT) ,0) + lowertemp.react() + T.assume_air(lowertemp) + qdel(hotspot) + if(G.toxins) + G.nitrogen += (G.toxins) + G.toxins = 0 + for(var/obj/machinery/atmospherics/unary/vent_pump/V in T) + V.welded = 1 + V.update_icon() + V.visible_message("[V] was frozen shut!") + for(var/mob/living/L in T) + L.ExtinguishMob() + return + +/datum/effect/effect/system/freezing_smoke_spread + +/datum/effect/effect/system/freezing_smoke_spread/set_up(n = 6, c = 0, loca) + number = n + if(istype(loca, /turf/)) + location = loca + else + location = get_turf(loca) + +/datum/effect/effect/system/freezing_smoke_spread/start() + var/i = 0 + for(i=0, i=7)//If turf was not found or they're on z level 2 or >7 which does not currently exist. + if(!current_location||(current_location.z in config.admin_levels)||current_location.z>=7)//If turf was not found or they're on z level 2 or >7 which does not currently exist. user << "\The [src] is malfunctioning." return var/list/L = list( ) diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index 9691f3213ba..e925b39de25 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -20,7 +20,7 @@ desc = "A wrench with common uses. Can be found in your hand." icon = 'icons/obj/items.dmi' icon_state = "wrench" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT force = 5.0 throwforce = 7.0 @@ -38,7 +38,7 @@ desc = "You can be totally screwwy with this." icon = 'icons/obj/items.dmi' icon_state = "screwdriver" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT force = 5.0 w_class = 1.0 @@ -87,7 +87,7 @@ if(!istype(M)) return ..() if(user.zone_sel.selecting != "eyes" && user.zone_sel.selecting != "head") return ..() - if((M_CLUMSY in user.mutations) && prob(50)) + if((CLUMSY in user.mutations) && prob(50)) M = user return eyestab(M,user) @@ -99,7 +99,7 @@ desc = "This cuts wires." icon = 'icons/obj/items.dmi' icon_state = "cutters" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT force = 6.0 throw_speed = 3 @@ -118,7 +118,7 @@ item_state = "cutters_yellow" /obj/item/weapon/wirecutters/attack(mob/living/carbon/C as mob, mob/user as mob) - if((C.handcuffed) && (istype(C.handcuffed, /obj/item/weapon/handcuffs/cable))) + if((C.handcuffed) && (istype(C.handcuffed, /obj/item/weapon/restraints/handcuffs/cable))) usr.visible_message("\The [usr] cuts \the [C]'s restraints with \the [src]!",\ "You cut \the [C]'s restraints with \the [src]!",\ "You hear cable being cut.") @@ -135,7 +135,7 @@ name = "welding tool" icon = 'icons/obj/items.dmi' icon_state = "welder" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT //Amount of OUCH when it's thrown @@ -147,7 +147,7 @@ //Cost to make in the autolathe m_amt = 70 - g_amt = 30 + g_amt = 20 //R&D tech level origin_tech = "engineering=1" @@ -172,7 +172,7 @@ return -/obj/item/weapon/weldingtool/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/weapon/weldingtool/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/screwdriver)) if(welding) user << "\red Stop welding first!" @@ -194,12 +194,12 @@ if (user.client) user.client.screen -= src if (user.r_hand == src) - user.u_equip(src) + user.unEquip(src) else - user.u_equip(src) + user.unEquip(src) src.master = F src.layer = initial(src.layer) - user.u_equip(src) + user.unEquip(src) if (user.client) user.client.screen -= src src.loc = F @@ -447,7 +447,7 @@ desc = "A small crowbar. This handy tool is useful for lots of things, such as prying floor tiles or opening unpowered doors." icon = 'icons/obj/items.dmi' icon_state = "crowbar" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT force = 5.0 throwforce = 7.0 @@ -514,7 +514,7 @@ desc = "A professional conversion kit used to convert any knock off revolver into the real deal capable of shooting lethal .357 rounds without the possibility of catastrophic failure" icon = 'icons/obj/weapons.dmi' icon_state = "kit" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT w_class = 2.0 origin_tech = "combat=2" var/open = 0 diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index f38c9b477f3..5f5d913823b 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -107,7 +107,7 @@ w_class = 5.0 icon_state = "offhand" name = "offhand" - //flags = ABSTRACT + flags = ABSTRACT /obj/item/weapon/twohanded/offhand/unwield() del(src) @@ -207,7 +207,7 @@ obj/item/weapon/twohanded/ force_wielded = 34 wieldsound = 'sound/weapons/saberon.ogg' unwieldsound = 'sound/weapons/saberoff.ogg' - flags = FPRINT | TABLEPASS | NOSHIELD + flags = NOSHIELD origin_tech = "magnets=3;syndicate=4" attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") sharp = 1 @@ -227,7 +227,7 @@ obj/item/weapon/twohanded/ /obj/item/weapon/twohanded/dualsaber/attack(target as mob, mob/living/user as mob) ..() - if((M_CLUMSY in user.mutations) && (wielded) &&prob(40)) + if((CLUMSY in user.mutations) && (wielded) &&prob(40)) user << "\red You twirl around a bit before losing your balance and impaling yourself on the [src]." user.take_organ_damage(20,25) return @@ -267,7 +267,7 @@ obj/item/weapon/twohanded/ ..() hitsound = 'sound/weapons/blade1.ogg' -/obj/item/weapon/twohanded/dualsaber/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/twohanded/dualsaber/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if(istype(W, /obj/item/device/multitool)) if(hacked == 0) @@ -291,7 +291,7 @@ obj/item/weapon/twohanded/ force_wielded = 18 // Was 13, Buffed - RR throwforce = 20 throw_speed = 3 - flags = FPRINT | TABLEPASS | NOSHIELD + flags = NOSHIELD attack_verb = list("attacked", "poked", "jabbed", "torn", "gored") /obj/item/weapon/twohanded/spear/update_icon() @@ -444,7 +444,7 @@ obj/item/weapon/twohanded/ no_embed = 1 force = 5 force_unwielded = 5 - force_wielded = 20 + force_wielded = 30 throwforce = 15 throw_range = 1 w_class = 5 @@ -475,29 +475,31 @@ obj/item/weapon/twohanded/ /obj/item/weapon/twohanded/knighthammer/afterattack(atom/A as mob|obj|turf|area, mob/user as mob, proximity) if(!proximity) return - if(wielded) - if(charged == 5) - charged = 0 - if(istype(A, /mob/living/)) - var/mob/living/Z = A - if(Z.health < 1) - Z.visible_message("[Z.name] was blown to peices by the power of [src.name]!", \ - "You feel a powerful blow rip you apart!", \ - "You hear a heavy impact and the sound of ripping flesh!.") - Z.gib() - else - Z.take_organ_damage(0,30) - Z.visible_message("[Z.name] was sent flying by a blow from the [src.name]!", \ - "You feel a powerful blow connect with your body and send you flying!", \ - "You hear something heavy impact flesh!.") - var/atom/throw_target = get_edge_target_turf(Z, get_dir(src, get_step_away(Z, src))) - Z.throw_at(throw_target, 200, 4) - else if(istype(A, /turf/simulated/wall)) + if(charged == 5) + charged = 0 + if(istype(A, /mob/living/)) + var/mob/living/Z = A + if(Z.health >= 1) + Z.visible_message("[Z.name] was sent flying by a blow from the [src.name]!", \ + "You feel a powerful blow connect with your body and send you flying!", \ + "You hear something heavy impact flesh!.") + var/atom/throw_target = get_edge_target_turf(Z, get_dir(src, get_step_away(Z, src))) + Z.throw_at(throw_target, 200, 4) + playsound(user, 'sound/weapons/marauder.ogg', 50, 1) + else if(wielded && Z.health < 1) + Z.visible_message("[Z.name] was blown to peices by the power of [src.name]!", \ + "You feel a powerful blow rip you apart!", \ + "You hear a heavy impact and the sound of ripping flesh!.") + Z.gib() + playsound(user, 'sound/weapons/marauder.ogg', 50, 1) + if(wielded) + if(istype(A, /turf/simulated/wall)) var/turf/simulated/wall/Z = A Z.ex_act(2) charged = 3 + playsound(user, 'sound/weapons/marauder.ogg', 50, 1) else if (istype(A, /obj/structure) || istype(A, /obj/mecha/)) var/obj/Z = A Z.ex_act(2) charged = 3 - playsound(user, 'sound/weapons/marauder.ogg', 50, 1) + playsound(user, 'sound/weapons/marauder.ogg', 50, 1) diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index 43618e46b73..d63f07d4e06 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -3,7 +3,6 @@ name = "banhammer" icon = 'icons/obj/items.dmi' icon_state = "toyhammer" - flags = FPRINT | TABLEPASS slot_flags = SLOT_BELT throwforce = 0 w_class = 1.0 @@ -21,7 +20,6 @@ desc = "A rod of pure obsidian, its very presence disrupts and dampens the powers of paranormal phenomenae." icon_state = "nullrod" item_state = "nullrod" - flags = FPRINT | TABLEPASS slot_flags = SLOT_BELT force = 15 throw_speed = 1 @@ -49,7 +47,7 @@ user << "\red You don't have the dexterity to do this!" return - if ((M_CLUMSY in user.mutations) && prob(50)) + if ((CLUMSY in user.mutations) && prob(50)) user << "\red The rod slips out of your hand and hits your head." user.take_organ_damage(10) user.Paralyse(20) @@ -74,7 +72,6 @@ desc = "This thing is so unspeakably shitty you are having a hard time even holding it." icon_state = "sord" item_state = "sord" - flags = FPRINT | TABLEPASS slot_flags = SLOT_BELT force = 2 throwforce = 1 @@ -96,7 +93,7 @@ desc = "What are you standing around staring at this for? Get to killing!" icon_state = "claymore" item_state = "claymore" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT hitsound = 'sound/weapons/bladeslice.ogg' slot_flags = SLOT_BELT force = 40 @@ -113,12 +110,17 @@ viewers(user) << "[user] is falling on the [src.name]! It looks like \he's trying to commit suicide." return(BRUTELOSS) +/obj/item/weapon/claymore/ceremonial + name = "ceremonial claymore" + desc = "An engraved and fancy version of the claymore. It appears to be less sharp than it's more functional cousin." + force = 20 + /obj/item/weapon/katana name = "katana" desc = "Woefully underpowered in D20" icon_state = "katana" item_state = "katana" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT | SLOT_BACK force = 40 throwforce = 10 @@ -156,20 +158,20 @@ obj/item/weapon/wirerod desc = "A rod with some wire wrapped around the top. It'd be easy to attach something to the top bit." icon_state = "wiredrod" item_state = "rods" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT force = 9 throwforce = 10 w_class = 3 m_amt = 1875 attack_verb = list("hit", "bludgeoned", "whacked", "bonked") -obj/item/weapon/wirerod/attackby(var/obj/item/I, mob/user as mob) +obj/item/weapon/wirerod/attackby(var/obj/item/I, mob/user as mob, params) ..() if(istype(I, /obj/item/weapon/shard)) var/obj/item/weapon/twohanded/spear/S = new /obj/item/weapon/twohanded/spear - user.u_equip(I) - user.u_equip(src) + user.unEquip(I) + user.unEquip(src) user.put_in_hands(S) user << "You fasten the glass shard to the top of the rod with the cable." @@ -179,8 +181,8 @@ obj/item/weapon/wirerod/attackby(var/obj/item/I, mob/user as mob) else if(istype(I, /obj/item/weapon/wirecutters)) var/obj/item/weapon/melee/baton/cattleprod/P = new /obj/item/weapon/melee/baton/cattleprod - user.u_equip(I) - user.u_equip(src) + user.unEquip(I) + user.unEquip(src) user.put_in_hands(P) user << "You fasten the wirecutters to the top of the rod with the cable, prongs outward." diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index a2cec2ac512..168134c6591 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -20,6 +20,28 @@ // What reagents should be logged when transferred TO this object? // Reagent ID => friendly name var/list/reagents_to_log=list() + +/obj/Topic(href, href_list, var/nowindow = 0, var/datum/topic_state/custom_state = default_state) + // Calling Topic without a corresponding window open causes runtime errors + if(!nowindow && ..()) + return 1 + + // In the far future no checks are made in an overriding Topic() beyond if(..()) return + // Instead any such checks are made in CanUseTopic() + var/obj/host = nano_host() + if(host.CanUseTopic(usr, href_list, custom_state) == STATUS_INTERACTIVE) + CouldUseTopic(usr) + return 0 + + CouldNotUseTopic(usr) + return 1 + +/obj/proc/CouldUseTopic(var/mob/user) + var/atom/host = nano_host() + host.add_fingerprint(user) + +/obj/proc/CouldNotUseTopic(var/mob/user) + // Nada /obj/Destroy() machines -= src diff --git a/code/game/objects/random/random.dm b/code/game/objects/random/random.dm index 832227b12d7..9b12b3dcc46 100644 --- a/code/game/objects/random/random.dm +++ b/code/game/objects/random/random.dm @@ -56,11 +56,11 @@ icon = 'icons/obj/power.dmi' icon_state = "cell" item_to_spawn() - return pick(prob(10);/obj/item/weapon/cell/crap,\ - prob(40);/obj/item/weapon/cell,\ - prob(40);/obj/item/weapon/cell/high,\ - prob(9);/obj/item/weapon/cell/super,\ - prob(1);/obj/item/weapon/cell/hyper) + return pick(prob(10);/obj/item/weapon/stock_parts/cell/crap,\ + prob(40);/obj/item/weapon/stock_parts/cell,\ + prob(40);/obj/item/weapon/stock_parts/cell/high,\ + prob(9);/obj/item/weapon/stock_parts/cell/super,\ + prob(1);/obj/item/weapon/stock_parts/cell/hyper) /obj/random/bomb_supply @@ -94,7 +94,7 @@ item_to_spawn() return pick(prob(3);/obj/random/powercell,\ prob(2);/obj/random/technology_scanner,\ - prob(1);/obj/item/weapon/packageWrap,\ + prob(1);/obj/item/stack/packageWrap,\ prob(2);/obj/random/bomb_supply,\ prob(1);/obj/item/weapon/extinguisher,\ prob(1);/obj/item/clothing/gloves/fyellow,\ diff --git a/code/game/objects/storage/coat.dm b/code/game/objects/storage/coat.dm deleted file mode 100644 index e5151ae5ded..00000000000 --- a/code/game/objects/storage/coat.dm +++ /dev/null @@ -1,224 +0,0 @@ -/obj/item/clothing/suit/storage - var/list/can_hold = new/list() //List of objects which this item can store (if set, it can't store anything else) - var/list/cant_hold = new/list() //List of objects which this item can't store (in effect only if can_hold isn't set) - var/max_w_class = 2 //Max size of objects that this object can store (in effect only if can_hold isn't set) - var/max_combined_w_class = 4 //The sum of the w_classes of all the items in this storage item. - var/storage_slots = 2 //The number of storage slots in this container. - var/obj/screen/storage/boxes = null - var/obj/screen/close/closer = null - -/obj/item/clothing/suit/storage/proc/return_inv() - - var/list/L = list( ) - - L += src.contents - - for(var/obj/item/weapon/storage/S in src) - L += S.return_inv() - for(var/obj/item/weapon/gift/G in src) - L += G.gift - if (istype(G.gift, /obj/item/weapon/storage)) - L += G.gift:return_inv() - return L - -/obj/item/clothing/suit/storage/proc/show_to(mob/user as mob) - user.client.screen -= src.boxes - user.client.screen -= src.closer - user.client.screen -= src.contents - user.client.screen += src.boxes - user.client.screen += src.closer - user.client.screen += src.contents - user.s_active = src - return - -/obj/item/clothing/suit/storage/proc/hide_from(mob/user as mob) - - if(!user.client) - return - user.client.screen -= src.boxes - user.client.screen -= src.closer - user.client.screen -= src.contents - return - -/obj/item/clothing/suit/storage/proc/close(mob/user as mob) - - src.hide_from(user) - user.s_active = null - return - -//This proc draws out the inventory and places the items on it. tx and ty are the upper left tile and mx, my are the bottm right. -//The numbers are calculated from the bottom-left The bottom-left slot being 1,1. -/obj/item/clothing/suit/storage/proc/orient_objs(tx, ty, mx, my) - var/cx = tx - var/cy = ty - src.boxes.screen_loc = text("[tx]:,[ty] to [mx],[my]") - for(var/obj/O in src.contents) - O.screen_loc = text("[cx],[cy]") - O.layer = 20 - cx++ - if (cx > mx) - cx = tx - cy-- - src.closer.screen_loc = text("[mx+1],[my]") - return - -//This proc draws out the inventory and places the items on it. It uses the standard position. -/obj/item/clothing/suit/storage/proc/standard_orient_objs(var/rows,var/cols) - var/cx = 4 - var/cy = 2+rows - src.boxes.screen_loc = text("4:16,2:16 to [4+cols]:16,[2+rows]:16") - for(var/obj/O in src.contents) - O.screen_loc = text("[cx]:16,[cy]:16") - O.layer = 20 - cx++ - if (cx > (4+cols)) - cx = 4 - cy-- - src.closer.screen_loc = text("[4+cols+1]:16,2:16") - return - -//This proc determins the size of the inventory to be displayed. Please touch it only if you know what you're doing. -/obj/item/clothing/suit/storage/proc/orient2hud(mob/user as mob) - //var/mob/living/carbon/human/H = user - var/row_num = 0 - var/col_count = min(7,storage_slots) -1 - if (contents.len > 7) - row_num = round((contents.len-1) / 7) // 7 is the maximum allowed width. - src.standard_orient_objs(row_num,col_count) - return - -//This proc is called when you want to place an item into the storage item. -/obj/item/clothing/suit/storage/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W,/obj/item/weapon/evidencebag) && src.loc != user) - return - - ..() - if(isrobot(user)) - user << "\blue You're a robot. No." - return //Robots can't interact with storage items. - - if(src.loc == W) - return //Means the item is already in the storage item - - if(contents.len >= storage_slots) - user << "\red \The [src] is full, make some space." - return //Storage item is full - - if(can_hold.len) - var/ok = 0 - for(var/A in can_hold) - if(istype(W, text2path(A) )) - ok = 1 - break - if(!ok) - user << "\red \The [src] cannot hold \the [W]." - return - - for(var/A in cant_hold) //Check for specific items which this container can't hold. - if(istype(W, text2path(A) )) - user << "\red \The [src] cannot hold \the [W]." - return - - if (W.w_class > max_w_class) - user << "\red \The [W] is too big for \the [src]" - return - - var/sum_w_class = W.w_class - for(var/obj/item/I in contents) - sum_w_class += I.w_class //Adds up the combined w_classes which will be in the storage item if the item is added to it. - - if(sum_w_class > max_combined_w_class) - user << "\red \The [src] is full, make some space." - return - - if(W.w_class >= src.w_class && (istype(W, /obj/item/weapon/storage))) - if(!istype(src, /obj/item/weapon/storage/backpack/holding)) //bohs should be able to hold backpacks again. The override for putting a boh in a boh is in backpack.dm. - user << "\red \The [src] cannot hold \the [W] as it's a storage item of the same size." - return //To prevent the stacking of the same sized items. - - user.u_equip(W) - playsound(src.loc, "rustle", 50, 1, -5) - W.loc = src - if ((user.client && user.s_active != src)) - user.client.screen -= W - src.orient2hud(user) - W.dropped(user) - add_fingerprint(user) - show_to(user) - - -/obj/item/weapon/storage/dropped(mob/user as mob) - return - -/obj/item/clothing/suit/storage/MouseDrop(atom/over_object) - if(ishuman(usr)) - var/mob/living/carbon/human/M = usr - if (!( istype(over_object, /obj/screen) )) - return ..() - playsound(src.loc, "rustle", 50, 1, -5) - if ((!( M.restrained() ) && !( M.stat ) && M.wear_suit == src)) - if (over_object.name == "r_hand") - M.u_equip(src) - M.put_in_r_hand(src) - // if (!( M.r_hand )) - // M.u_equip(src) - // M.r_hand = src - else if (over_object.name == "l_hand") - M.u_equip(src) - M.put_in_l_hand(src) - // if (!( M.l_hand )) - // M.u_equip(src) - // M.l_hand = src - M.update_inv_wear_suit() - src.add_fingerprint(usr) - return - if( (over_object == usr && in_range(src, usr) || usr.contents.Find(src)) && usr.s_active) - usr.s_active.close(usr) - src.show_to(usr) - return - -/obj/item/clothing/suit/storage/attack_paw(mob/user as mob) - //playsound(src.loc, "rustle", 50, 1, -5) // what - return src.attack_hand(user) - -/obj/item/clothing/suit/storage/attack_hand(mob/user as mob) - playsound(src.loc, "rustle", 50, 1, -5) - src.orient2hud(user) - if (src.loc == user) - if (user.s_active) - user.s_active.close(user) - src.show_to(user) - else - ..() - for(var/mob/M in range(1)) - if (M.s_active == src) - src.close(M) - src.add_fingerprint(user) - return - -/obj/item/clothing/suit/storage/New() - - src.boxes = new /obj/screen/storage( ) - src.boxes.name = "storage" - src.boxes.master = src - src.boxes.icon_state = "block" - src.boxes.screen_loc = "7,7 to 10,8" - src.boxes.layer = 19 - src.closer = new /obj/screen/close( ) - src.closer.master = src - src.closer.icon_state = "x" - src.closer.layer = 20 - orient2hud() - return - -/obj/item/clothing/suit/emp_act(severity) - if(!istype(src.loc, /mob/living)) - for(var/obj/O in contents) - O.emp_act(severity) - ..() - -/obj/item/clothing/suit/hear_talk(mob/M, var/msg) - for (var/atom/A in src) - if(istype(A,/obj/)) - var/obj/O = A - O.hear_talk(M, msg) \ No newline at end of file diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index 1f98e54cb75..197da35056d 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -25,7 +25,8 @@ /obj/structure/Destroy() if(hascall(src, "unbuckle")) src:unbuckle() - + ..() + /obj/structure/mech_melee_attack(obj/mecha/M) if(M.damtype == "brute") M.occupant_message("You hit [src].") diff --git a/code/game/objects/structures/barsign.dm b/code/game/objects/structures/barsign.dm index f6298edf7be..532454b445f 100644 --- a/code/game/objects/structures/barsign.dm +++ b/code/game/objects/structures/barsign.dm @@ -3,7 +3,7 @@ icon_state = "empty" anchored = 1 New() - ChangeSign(pick("pinkflamingo", "magmasea", "limbo", "rustyaxe", "armokbar", "brokendrum", "meadbay", "thedamnwall", "thecavern", "cindikate", "theorchard", "thesaucyclown", "theclownshead","lv426", "zocalo", "4theemprah", "ishimura", "tardis", "quarks", "tenforward", "thepranicngpony", "vault13", "solaris", "thehive", "cantina", "theouterspess", "milliways42", "thetimeofeve", "spaceasshole", "dwarffortress")) + ChangeSign(pick("magmasea", "limbo", "rustyaxe", "armokbar", "brokendrum", "meadbay", "thecavern", "cindikate", "theorchard", "lv426", "zocalo", "4theemprah", "ishimura", "tardis", "quarks", "tenforward", "thepranicngpony", "vault13", "solaris", "thehive", "cantina", "theouterspess", "milliways42", "thetimeofeve", "spaceasshole", "dwarffortress", "thebark", "thedrunkcarp", "theharmbaton", "thenest", "officerbeersky", "thesingulo")) return proc/ChangeSign(var/Text) src.icon_state = "[Text]" diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index 19cfca4eaf4..3b37a08299c 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -178,7 +178,7 @@ LINEN BINS else icon_state = "linenbin-full" -/obj/structure/bedsheetbin/attackby(obj/item/I as obj, mob/user as mob) +/obj/structure/bedsheetbin/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/weapon/bedsheet)) user.drop_item() I.loc = src diff --git a/code/game/objects/structures/coathanger.dm b/code/game/objects/structures/coathanger.dm index b79588b78f3..13136868954 100644 --- a/code/game/objects/structures/coathanger.dm +++ b/code/game/objects/structures/coathanger.dm @@ -13,7 +13,7 @@ coat = null update_icon() -/obj/structure/coatrack/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/coatrack/attackby(obj/item/weapon/W as obj, mob/user as mob, params) var/can_hang = 0 for (var/T in allowed) if(istype(W,T)) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 7f2ed7e1b3e..1375ed71d61 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -4,7 +4,6 @@ icon = 'icons/obj/closet.dmi' icon_state = "closed" density = 1 - flags = FPRINT var/icon_closed = "closed" var/icon_opened = "open" var/opened = 0 @@ -163,6 +162,7 @@ /obj/structure/closet/attack_animal(mob/living/simple_animal/user as mob) if(user.environment_smash) + user.do_attack_animation(src) visible_message("\red [user] destroys the [src]. ") for(var/atom/movable/A as mob|obj in src) A.loc = src.loc @@ -182,7 +182,7 @@ src.dump_contents() del(src) -/obj/structure/closet/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/closet/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/rcs) && !src.opened) var/obj/item/weapon/rcs/E = W if(E.rcharges != 0) @@ -262,10 +262,11 @@ return if(isrobot(user)) return - usr.drop_item() + if(!usr.drop_item()) + return if(W) W.loc = src.loc - else if(istype(W, /obj/item/weapon/packageWrap)) + else if(istype(W, /obj/item/stack/packageWrap)) return else if(istype(W, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/WT = W diff --git a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm index 87eb2cb8114..14807277647 100644 --- a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm +++ b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm @@ -14,14 +14,14 @@ var/locked = 1 var/smashed = 0 - attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri + attackby(var/obj/item/O as obj, var/mob/living/user as mob) //Marker -Agouri //..() //That's very useful, Erro var/hasaxe = 0 //gonna come in handy later~ if(fireaxe) hasaxe = 1 - if (isrobot(usr) || src.locked) + if (isrobot(user) || src.locked) if(istype(O, /obj/item/device/multitool)) user << "\red Resetting circuitry..." playsound(user, 'sound/machines/lockreset.ogg', 50, 1) @@ -31,6 +31,7 @@ update_icon() return else if(istype(O, /obj/item/weapon)) + user.changeNext_move(CLICK_CD_MELEE) var/obj/item/weapon/W = O if(src.smashed || src.localopened) if(localopened) @@ -39,6 +40,7 @@ spawn(10) update_icon() return else + user.do_attack_animation(src) playsound(user, 'sound/effects/Glasshit.ogg', 100, 1) //We don't want this playing every time if(W.force < 15) user << "\blue The cabinet's protective glass glances off the hit." diff --git a/code/game/objects/structures/crates_lockers/closets/job_closets.dm b/code/game/objects/structures/crates_lockers/closets/job_closets.dm index af199c0397c..42e82b8af22 100644 --- a/code/game/objects/structures/crates_lockers/closets/job_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/job_closets.dm @@ -85,6 +85,7 @@ new /obj/item/weapon/holosign_creator(src) new /obj/item/clothing/gloves/black(src) new /obj/item/clothing/head/soft/purple(src) + new /obj/item/weapon/watertank/janitor(src) new /obj/item/weapon/storage/belt/janitor(src) /* diff --git a/code/game/objects/structures/crates_lockers/closets/malfunction.dm b/code/game/objects/structures/crates_lockers/closets/malfunction.dm index 7cfb4f18e2f..3bf64ba34d8 100644 --- a/code/game/objects/structures/crates_lockers/closets/malfunction.dm +++ b/code/game/objects/structures/crates_lockers/closets/malfunction.dm @@ -13,5 +13,5 @@ new /obj/item/clothing/head/helmet/space/nasavoid(src) new /obj/item/clothing/suit/space/nasavoid(src) new /obj/item/weapon/crowbar(src) - new /obj/item/weapon/cell(src) + new /obj/item/weapon/stock_parts/cell(src) new /obj/item/device/multitool(src) \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm index 6515018e541..1fbd663ef9e 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm @@ -144,6 +144,7 @@ new /obj/item/clothing/suit/storage/hazardvest(src) new /obj/item/clothing/mask/gas(src) new /obj/item/weapon/tank/emergency_oxygen/engi(src) + new /obj/item/weapon/watertank/atmos(src) new /obj/item/clothing/suit/fire/atmos(src) new /obj/item/clothing/head/hardhat/atmos(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm b/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm index df408e80926..8ac793d8de3 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm @@ -22,7 +22,7 @@ new /obj/item/device/analyzer/plant_analyzer(src) new /obj/item/device/radio/headset/headset_service(src) new /obj/item/device/radio/headset/headset_service(src) - new /obj/item/clothing/head/greenbandana(src) + new /obj/item/clothing/mask/bandana/botany(src) new /obj/item/weapon/minihoe(src) new /obj/item/weapon/hatchet(src) new /obj/item/weapon/bee_net(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index 9e0ffec3dd8..c223fa99314 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -148,7 +148,7 @@ new /obj/item/clothing/shoes/brown (src) new /obj/item/device/radio/headset/heads/cmo(src) new /obj/item/clothing/gloves/color/latex/nitrile(src) - new /obj/item/weapon/defibrillator/loaded(src) + new /obj/item/weapon/defibrillator/compact/loaded(src) new /obj/item/weapon/storage/belt/medical(src) new /obj/item/device/flash(src) new /obj/item/weapon/reagent_containers/hypospray/CMO(src) @@ -234,4 +234,6 @@ sleep(2) new /obj/item/clothing/suit/space/eva/paramedic(src) new /obj/item/clothing/head/helmet/space/eva/paramedic(src) + new /obj/item/clothing/head/helmet/space/eva/paramedic(src) + new /obj/item/device/sensor_device(src) return \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm index f48a0e69e4f..9d14c48765c 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm @@ -58,7 +58,7 @@ new /obj/item/device/radio/headset( src ) return -/obj/structure/closet/secure_closet/personal/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/closet/secure_closet/personal/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (src.opened) if (istype(W, /obj/item/weapon/grab)) src.MouseDrop_T(W:affecting, user) //act like they were dragged onto the closet @@ -75,10 +75,14 @@ else if(src.allowed(user) || !src.registered_name || (istype(I) && (src.registered_name == I.registered_name))) //they can open all lockers, or nobody owns this, or they own this locker src.locked = !( src.locked ) - if(src.locked) src.icon_state = src.icon_locked - else src.icon_state = src.icon_closed + if(src.locked) + src.icon_state = src.icon_locked + else + src.icon_state = src.icon_closed + registered_name = null + desc = initial(desc) - if(!src.registered_name) + if(!src.registered_name && src.locked) src.registered_name = I.registered_name src.desc = "Owned by [I.registered_name]." else diff --git a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm index 23dc36da2a1..7d3fde7744c 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm @@ -65,7 +65,7 @@ else user << "Access Denied" -/obj/structure/closet/secure_closet/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/closet/secure_closet/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(src.opened) if(istype(W, /obj/item/weapon/grab)) if(src.large) @@ -94,7 +94,7 @@ else for(var/mob/O in viewers(user, 3)) O.show_message("The locker has been broken by [user] with an electromagnetic card!", 1, "You hear a faint electrical spark.", 2) - else if(istype(W,/obj/item/weapon/packageWrap) || istype(W,/obj/item/weapon/weldingtool)) + else if(istype(W,/obj/item/stack/packageWrap) || istype(W,/obj/item/weapon/weldingtool)) return ..(W,user) else togglelock(user) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 7bc09593e5e..ae57669c261 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -112,12 +112,12 @@ new /obj/item/clothing/glasses/sunglasses/sechud(src) new /obj/item/weapon/storage/lockbox/loyalty(src) new /obj/item/weapon/storage/box/flashbangs(src) - new /obj/item/clothing/mask/gas/sechailer/hos(src) - new /obj/item/weapon/shield/riot(src) + new /obj/item/clothing/mask/gas/sechailer/swat(src) + new /obj/item/weapon/shield/riot/tele(src) new /obj/item/weapon/melee/baton/loaded(src) - new /obj/item/weapon/gun/energy/advtaser(src) new /obj/item/weapon/storage/belt/security(src) new /obj/item/taperoll/police(src) + new /obj/item/weapon/gun/energy/hos(src) return @@ -148,9 +148,9 @@ new /obj/item/clothing/under/rank/warden(src) new /obj/item/clothing/under/rank/warden/formal(src) new /obj/item/clothing/glasses/sunglasses/sechud(src) - new /obj/item/clothing/mask/gas/sechailer/warden(src) + new /obj/item/clothing/mask/gas/sechailer(src) new /obj/item/taperoll/police(src) - new /obj/item/weapon/storage/box/handcuffs(src) + new /obj/item/weapon/storage/box/zipties(src) new /obj/item/weapon/storage/box/flashbangs(src) new /obj/item/weapon/reagent_containers/spray/pepper(src) new /obj/item/weapon/melee/baton/loaded(src) @@ -240,7 +240,7 @@ new /obj/item/weapon/storage/belt/security(src) new /obj/item/weapon/grenade/flashbang(src) new /obj/item/device/flash(src) - new /obj/item/weapon/handcuffs(src) + new /obj/item/weapon/restraints/handcuffs(src) new /obj/item/weapon/melee/baton/loaded(src) new /obj/item/clothing/glasses/sunglasses(src) new /obj/item/clothing/glasses/hud/health_advanced @@ -248,7 +248,8 @@ new /obj/item/clothing/under/rank/centcom_officer(src) new /obj/item/clothing/suit/armor/vest/fluff/deus_blueshield(src) new /obj/item/clothing/shoes/centcom(src) - new /obj/item/clothing/tie/blue(src) + new /obj/item/clothing/accessory/holster(src) + new /obj/item/clothing/accessory/blue(src) return /obj/structure/closet/secure_closet/ntrep @@ -281,7 +282,7 @@ New() ..() - new /obj/item/clothing/tie/armband/cargo(src) + new /obj/item/clothing/accessory/armband/cargo(src) new /obj/item/device/encryptionkey/headset_cargo(src) return @@ -289,7 +290,7 @@ New() ..() - new /obj/item/clothing/tie/armband/engine(src) + new /obj/item/clothing/accessory/armband/engine(src) new /obj/item/device/encryptionkey/headset_eng(src) return @@ -297,7 +298,7 @@ New() ..() - new /obj/item/clothing/tie/armband/science(src) + new /obj/item/clothing/accessory/armband/science(src) new /obj/item/device/encryptionkey/headset_sci(src) return @@ -305,7 +306,7 @@ New() ..() - new /obj/item/clothing/tie/armband/medgreen(src) + new /obj/item/clothing/accessory/armband/medgreen(src) new /obj/item/device/encryptionkey/headset_med(src) return @@ -339,7 +340,7 @@ new /obj/item/ammo_box/c38(src) new /obj/item/weapon/gun/projectile/revolver/detective(src) new /obj/item/taperoll/police(src) - new /obj/item/clothing/tie/holster/armpit(src) + new /obj/item/clothing/accessory/holster/armpit(src) return /obj/structure/closet/secure_closet/detective/update_icon() diff --git a/code/game/objects/structures/crates_lockers/closets/statue.dm b/code/game/objects/structures/crates_lockers/closets/statue.dm index e089c4448f0..85696e2973e 100644 --- a/code/game/objects/structures/crates_lockers/closets/statue.dm +++ b/code/game/objects/structures/crates_lockers/closets/statue.dm @@ -5,7 +5,6 @@ icon_state = "human_male" density = 1 anchored = 1 - flags = FPRINT health = 0 //destroying the statue kills the mob within var/intialTox = 0 //these are here to keep the mob from taking damage from things that logically wouldn't affect a rock var/intialFire = 0 //it's a little sloppy I know but it was this or the GODMODE flag. Lesser of two evils. @@ -123,7 +122,7 @@ M.meteorhit(O) shatter(M) -/obj/structure/closet/statue/attackby(obj/item/I as obj, mob/user as mob) +/obj/structure/closet/statue/attackby(obj/item/I as obj, mob/user as mob, params) health -= I.force visible_message("\red [user] strikes [src] with [I].") if(health <= 0) diff --git a/code/game/objects/structures/crates_lockers/closets/syndicate.dm b/code/game/objects/structures/crates_lockers/closets/syndicate.dm index 01fceded7e6..09dcc02bafd 100644 --- a/code/game/objects/structures/crates_lockers/closets/syndicate.dm +++ b/code/game/objects/structures/crates_lockers/closets/syndicate.dm @@ -13,8 +13,7 @@ ..() sleep(2) new /obj/item/clothing/under/syndicate(src) - new /obj/item/clothing/suit/armor/vest(src) - new /obj/item/clothing/head/helmet/swat/syndicate(src) + new /obj/item/clothing/shoes/black(src) new /obj/item/ammo_box/magazine/m10mm(src) new /obj/item/weapon/storage/belt/military(src) new /obj/item/weapon/crowbar/red(src) @@ -26,8 +25,10 @@ /obj/structure/closet/syndicate/suits/New() ..() sleep(2) - new /obj/item/weapon/tank/jetpack/oxygen/harness(src) + new /obj/item/clothing/head/helmet/space/rig/syndi(src) new /obj/item/clothing/mask/gas/syndicate(src) + new /obj/item/clothing/suit/space/rig/syndi(src) + new /obj/item/weapon/tank/jetpack/oxygen/harness(src) new /obj/item/clothing/shoes/magboots/syndie(src) /obj/structure/closet/syndicate/nuclear diff --git a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm index 7a7accadd10..90cee7c97a8 100644 --- a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm +++ b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm @@ -8,6 +8,9 @@ new /obj/item/clothing/under/color/blue(src) new /obj/item/clothing/under/color/blue(src) new /obj/item/clothing/under/color/blue(src) + new /obj/item/clothing/mask/bandana/blue(src) + new /obj/item/clothing/mask/bandana/blue(src) + new /obj/item/clothing/mask/bandana/blue(src) new /obj/item/clothing/shoes/brown(src) new /obj/item/clothing/shoes/brown(src) new /obj/item/clothing/shoes/brown(src) @@ -22,6 +25,9 @@ /obj/structure/closet/wardrobe/red/New() new /obj/item/weapon/storage/backpack/duffel/security(src) new /obj/item/weapon/storage/backpack/duffel/security(src) + new /obj/item/clothing/mask/bandana/red(src) + new /obj/item/clothing/mask/bandana/red(src) + new /obj/item/clothing/mask/bandana/red(src) new /obj/item/clothing/under/rank/security(src) new /obj/item/clothing/under/rank/security(src) new /obj/item/clothing/under/rank/security(src) @@ -381,6 +387,10 @@ new /obj/item/clothing/head/soft/grey(src) if(prob(50)) new /obj/item/weapon/storage/backpack/duffel(src) + if(prob(40)) + new /obj/item/clothing/under/assistantformal(src) + if(prob(40)) + new /obj/item/clothing/under/assistantformal(src) return diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index fb60fa0d3aa..59edffe4b0d 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -10,6 +10,17 @@ climbable = 1 // mouse_drag_pointer = MOUSE_ACTIVE_POINTER //??? var/rigged = 0 + var/obj/item/weapon/paper/manifest/manifest + +/obj/structure/closet/crate/New() + ..() + update_icon() + +/obj/structure/closet/crate/update_icon() + ..() + overlays.Cut() + if(manifest) + overlays += "manifest" /obj/structure/closet/crate/can_open() return 1 @@ -67,7 +78,7 @@ src.opened = 0 return 1 -/obj/structure/closet/crate/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/closet/crate/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/rcs) && !src.opened) var/obj/item/weapon/rcs/E = W if(E.rcharges != 0) @@ -133,10 +144,12 @@ if(opened) if(isrobot(user)) return - user.drop_item() + if(!user.drop_item()) //couldn't drop the item + user << "\The [W] is stuck to your hand, you cannot put it in \the [src]!" + return if(W) W.loc = src.loc - else if(istype(W, /obj/item/weapon/packageWrap)) + else if(istype(W, /obj/item/stack/packageWrap)) return else if(istype(W, /obj/item/stack/cable_coil)) if(rigged) @@ -181,6 +194,29 @@ else return +/obj/structure/closet/crate/attack_hand(mob/user as mob) + if(manifest) + user << "You tear the manifest off of the crate." + playsound(src.loc, 'sound/items/poster_ripped.ogg', 75, 1) + manifest.loc = loc + if(ishuman(user)) + user.put_in_hands(manifest) + manifest = null + update_icon() + return + else + if(rigged && locate(/obj/item/device/radio/electropack) in src) + if(isliving(user)) + var/mob/living/L = user + if(L.electrocute_act(17, src)) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(5, 1, src) + s.start() + return + src.add_fingerprint(user) + src.toggle(user) + return + /obj/structure/closet/crate/secure desc = "A secure crate." name = "Secure crate" @@ -194,13 +230,16 @@ var/broken = 0 var/locked = 1 -/obj/structure/closet/crate/secure/New() +/obj/structure/closet/crate/secure/update_icon() ..() + overlays.Cut() + if(manifest) + overlays += "manifest" if(locked) - overlays.Cut() overlays += redlight + else if(broken) + overlays += emag else - overlays.Cut() overlays += greenlight /obj/structure/closet/crate/secure/can_open() @@ -218,8 +257,7 @@ for(var/mob/O in viewers(user, 3)) if((O.client && !( O.blinded ))) O << "The crate has been [locked ? null : "un"]locked by [user]." - overlays.Cut() - overlays += locked ? redlight : greenlight + update_icon() else user << "Access Denied" @@ -238,23 +276,31 @@ usr << "This mob type can't use this verb." /obj/structure/closet/crate/secure/attack_hand(mob/user as mob) - src.add_fingerprint(user) + if(manifest) + user << "You tear the manifest off of the crate." + playsound(src.loc, 'sound/items/poster_ripped.ogg', 75, 1) + manifest.loc = loc + if(ishuman(user)) + user.put_in_hands(manifest) + manifest = null + update_icon() + return if(locked) src.togglelock(user) else src.toggle(user) -/obj/structure/closet/crate/secure/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(is_type_in_list(W, list(/obj/item/weapon/packageWrap, /obj/item/stack/cable_coil, /obj/item/device/radio/electropack, /obj/item/weapon/wirecutters))) + +/obj/structure/closet/crate/secure/attackby(obj/item/weapon/W as obj, mob/user as mob, params) + if(is_type_in_list(W, list(/obj/item/stack/packageWrap, /obj/item/stack/cable_coil, /obj/item/device/radio/electropack, /obj/item/weapon/wirecutters))) return ..() if(locked && (istype(W, /obj/item/weapon/card/emag)||istype(W, /obj/item/weapon/melee/energy/blade))) - overlays.Cut() - overlays += emag overlays += sparks spawn(6) overlays -= sparks //Tried lots of stuff but nothing works right. so i have to use this *sadface* playsound(src.loc, "sparks", 60, 1) src.locked = 0 src.broken = 1 + update_icon() user << "You unlock \the [src]." return if(!opened) @@ -268,15 +314,12 @@ if(!broken && !opened && prob(50/severity)) if(!locked) src.locked = 1 - overlays.Cut() - overlays += redlight else - overlays.Cut() - overlays += emag overlays += sparks spawn(6) overlays -= sparks //Tried lots of stuff but nothing works right. so i have to use this *sadface* playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) src.locked = 0 + update_icon() if(!opened && prob(20/severity)) if(!locked) open() diff --git a/code/game/objects/structures/crates_lockers/crittercrate.dm b/code/game/objects/structures/crates_lockers/crittercrate.dm index 2f01821abc9..cdbdacde644 100644 --- a/code/game/objects/structures/crates_lockers/crittercrate.dm +++ b/code/game/objects/structures/crates_lockers/crittercrate.dm @@ -6,6 +6,7 @@ icon_closed = "critter" var/already_opened = 0 var/content_mob = null + var/amount = 1 /obj/structure/closet/critter/can_open() if(welded) @@ -21,19 +22,7 @@ return ..() if(content_mob != null && already_opened == 0) - if(content_mob == /mob/living/simple_animal/chick) - var/num = rand(4, 6) - for(var/i = 0, i < num, i++) - new content_mob(loc) - else if(content_mob == /mob/living/simple_animal/corgi) - var/num = rand(0, 1) - if(num) //No more matriarchy for cargo - content_mob = /mob/living/simple_animal/corgi/Lisa - new content_mob(loc) - else if(content_mob == /mob/living/simple_animal/cat) - if(prob(50)) - content_mob = /mob/living/simple_animal/cat/Proc - else + for(var/i = 1, i <= amount, i++) new content_mob(loc) already_opened = 1 ..() @@ -53,7 +42,12 @@ /obj/structure/closet/critter/corgi name = "corgi crate" - content_mob = /mob/living/simple_animal/corgi //This statement is (not) false. See above. + content_mob = /mob/living/simple_animal/corgi + +/obj/structure/closet/critter/corgi/New() + if(prob(50)) + content_mob = /mob/living/simple_animal/corgi/Lisa + ..() /obj/structure/closet/critter/cow name = "cow crate" @@ -67,10 +61,28 @@ name = "chicken crate" content_mob = /mob/living/simple_animal/chick +/obj/structure/closet/critter/chick/New() + amount = rand(1, 3) + ..() + /obj/structure/closet/critter/cat name = "cat crate" content_mob = /mob/living/simple_animal/cat +/obj/structure/closet/critter/cat/New() + if(prob(50)) + content_mob = /mob/living/simple_animal/cat/Proc + ..() + +/obj/structure/closet/critter/pug + name = "pug crate" + content_mob = /mob/living/simple_animal/pug + /obj/structure/closet/critter/fox name = "fox crate" - content_mob = /mob/living/simple_animal/fox \ No newline at end of file + content_mob = /mob/living/simple_animal/fox + +/obj/structure/closet/critter/butterfly + name = "butterflies crate" + content_mob = /mob/living/simple_animal/butterfly + amount = 50 \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/largecrate.dm b/code/game/objects/structures/crates_lockers/largecrate.dm index 96ed8ef9169..3d50826e03a 100644 --- a/code/game/objects/structures/crates_lockers/largecrate.dm +++ b/code/game/objects/structures/crates_lockers/largecrate.dm @@ -4,14 +4,38 @@ icon = 'icons/obj/storage.dmi' icon_state = "densecrate" density = 1 - flags = FPRINT + var/obj/item/weapon/paper/manifest/manifest + +/obj/structure/largecrate/New() + ..() + update_icon() + +/obj/structure/largecrate/update_icon() + ..() + overlays.Cut() + if(manifest) + overlays += "manifest" /obj/structure/largecrate/attack_hand(mob/user as mob) - user << "You need a crowbar to pry this open!" - return + if(manifest) + user << "You tear the manifest off of the crate." + playsound(src.loc, 'sound/items/poster_ripped.ogg', 75, 1) + manifest.loc = loc + if(ishuman(user)) + user.put_in_hands(manifest) + manifest = null + update_icon() + return + else + user << "You need a crowbar to pry this open!" + return -/obj/structure/largecrate/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/largecrate/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/crowbar)) + if(manifest) + manifest.loc = loc + manifest = null + update_icon() new /obj/item/stack/sheet/wood(src) var/turf/T = get_turf(src) for(var/obj/O in contents) @@ -38,7 +62,7 @@ name = "cow crate" icon_state = "lisacrate" -/obj/structure/largecrate/cow/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/largecrate/cow/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/crowbar)) new /mob/living/simple_animal/cow(loc) ..() @@ -47,7 +71,7 @@ name = "goat crate" icon_state = "lisacrate" -/obj/structure/largecrate/goat/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/largecrate/goat/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/crowbar)) new /mob/living/simple_animal/hostile/retaliate/goat(loc) ..() @@ -56,7 +80,7 @@ name = "chicken crate" icon_state = "lisacrate" -/obj/structure/largecrate/chick/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/largecrate/chick/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/crowbar)) var/num = rand(4, 6) for(var/i = 0, i < num, i++) @@ -67,7 +91,7 @@ name = "Mysterious Crate" icon_state = "lisacrate" -/obj/structure/largecrate/ninja/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/largecrate/ninja/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/crowbar)) new /obj/item/clothing/gloves/space_ninja(loc) new /obj/item/clothing/mask/gas/voice/space_ninja(loc) @@ -81,7 +105,7 @@ name = "cat crate" icon_state = "lisacrate" -/obj/structure/largecrate/cat/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/largecrate/cat/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/crowbar)) new /mob/living/simple_animal/cat(loc) ..() \ No newline at end of file diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 577e28c02f9..b7f18ced386 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -5,7 +5,7 @@ var/obj/item/weapon/airlock_electronics/circuit = null var/state=0 -/obj/structure/displaycase_frame/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/displaycase_frame/attackby(obj/item/weapon/W as obj, mob/user as mob, params) var/pstate=state var/turf/T=get_turf(src) switch(state) @@ -72,10 +72,11 @@ desc = "A display case for the captain's antique laser gun. It taunts you to kick it." /obj/structure/displaycase/captains_laser/New() - req_access = list(access_captain) - occupant = new /obj/item/weapon/gun/energy/laser/captain(src) + req_access = list(access_captain) locked = 1 - update_icon() + spawn(5) + occupant = new /obj/item/weapon/gun/energy/laser/captain(src) + update_icon() /obj/structure/proc/getPrint(mob/user as mob) return md5(user:dna:uni_identity) @@ -162,7 +163,7 @@ return -/obj/structure/displaycase/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/displaycase/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/card)) var/obj/item/weapon/card/id/I=W if(!check_access(I)) @@ -228,6 +229,8 @@ update_icon() else if(user.a_intent == "harm") + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) user.visible_message("\red [user.name] kicks \the [src]!", \ "\red You kick \the [src]!", \ "You hear glass crack.") diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm index 355ec779efe..1c178848899 100644 --- a/code/game/objects/structures/door_assembly.dm +++ b/code/game/objects/structures/door_assembly.dm @@ -135,7 +135,7 @@ obj/structure/door_assembly -/obj/structure/door_assembly/attackby(obj/item/W as obj, mob/user as mob) +/obj/structure/door_assembly/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/pen)) var/t = copytext(stripped_input(user, "Enter the name for the door.", src.name, src.created_name),1,MAX_NAME_LEN) if(!t) return diff --git a/code/game/objects/structures/dresser.dm b/code/game/objects/structures/dresser.dm index 6401ce034f3..6a773177c59 100644 --- a/code/game/objects/structures/dresser.dm +++ b/code/game/objects/structures/dresser.dm @@ -6,6 +6,15 @@ density = 1 anchored = 1 +/obj/structure/dresser/proc/convUnM(mund) + return underwear_m.Find(mund) + +/obj/structure/dresser/proc/convUnF(fund) + return underwear_f.Find(fund) + +/obj/structure/dresser/proc/convUs(us) + return undershirt_list.Find(us) + /obj/structure/dresser/attack_hand(mob/user as mob) if(!Adjacent(user))//no tele-grooming return @@ -18,14 +27,26 @@ return switch(choice) if("Underwear") - var/new_undies = input(user, "Select your underwear", "Changing") as null|anything in underwear_list - if(new_undies) - H.underwear = new_undies + if(H.gender == FEMALE) + var/new_undies = input(user, "Select your underwear", "Changing") as null|anything in underwear_f + if(new_undies) + H << "\red You selected [new_undies]." + var/freturn = convUnF(new_undies) + H.underwear = freturn + + else + var/new_undies = input(user, "Select your underwear", "Changing") as null|anything in underwear_m + if(new_undies) + H << "\red You selected [new_undies]." + var/mreturn = convUnM(new_undies) + H.underwear = mreturn if("Undershirt") var/new_undershirt = input(user, "Select your undershirt", "Changing") as null|anything in undershirt_list if(new_undershirt) - H.undershirt = new_undershirt + H << "\red You selected [new_undershirt]" + var/usreturn = convUs(new_undershirt) + H.undershirt = usreturn add_fingerprint(H) H.update_body() \ No newline at end of file diff --git a/code/game/objects/structures/electricchair.dm b/code/game/objects/structures/electricchair.dm index 828098fd07e..f9e49fcc40b 100644 --- a/code/game/objects/structures/electricchair.dm +++ b/code/game/objects/structures/electricchair.dm @@ -12,7 +12,7 @@ overlays += image('icons/obj/objects.dmi', src, "echair_over", MOB_LAYER + 1, dir) return -/obj/structure/stool/bed/chair/e_chair/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/stool/bed/chair/e_chair/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/wrench)) var/obj/structure/stool/bed/chair/C = new /obj/structure/stool/bed/chair(loc) playsound(loc, 'sound/items/Ratchet.ogg', 50, 1) diff --git a/code/game/objects/structures/engicart.dm b/code/game/objects/structures/engicart.dm index 1697fff9c48..85fee295e38 100644 --- a/code/game/objects/structures/engicart.dm +++ b/code/game/objects/structures/engicart.dm @@ -5,9 +5,6 @@ icon_state = "cart" anchored = 0 density = 1 - flags = OPENCONTAINER - //copypaste sorry - var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite var/obj/item/stack/sheet/glass/myglass = null var/obj/item/stack/sheet/metal/mymetal = null var/obj/item/stack/sheet/plasteel/myplasteel = null @@ -23,7 +20,7 @@ updateUsrDialog() user << "You put [I] into [src]." return -/obj/structure/engineeringcart/attackby(obj/item/I, mob/user) +/obj/structure/engineeringcart/attackby(obj/item/I, mob/user, params) var/fail_msg = "There is already one of those in [src]." if(!I.is_robot_module()) if(istype(I, /obj/item/stack/sheet/glass)) @@ -82,6 +79,21 @@ update_icon() else user << fail_msg + else if(istype(I, /obj/item/weapon/wrench)) + if (!anchored && !isinspace()) + playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) + user.visible_message( \ + "[user] tightens \the [src]'s casters.", \ + " You have tightened \the [src]'s casters.", \ + "You hear ratchet.") + anchored = 1 + else if(anchored) + playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) + user.visible_message( \ + "[user] loosens \the [src]'s casters.", \ + " You have loosened \the [src]'s casters.", \ + "You hear ratchet.") + anchored = 0 else usr << "You cannot interface your modules [src]!" diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm index cfcc3c1176d..80a6e4b34a8 100644 --- a/code/game/objects/structures/extinguisher.dm +++ b/code/game/objects/structures/extinguisher.dm @@ -9,7 +9,7 @@ var/opened = 0 -/obj/structure/extinguisher_cabinet/attackby(obj/item/O, mob/user) +/obj/structure/extinguisher_cabinet/attackby(obj/item/O, mob/user, params) if(isrobot(user) || isalien(user)) return if(istype(O, /obj/item/weapon/extinguisher)) diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm index 31cede5e65b..e00b7f1c366 100644 --- a/code/game/objects/structures/false_walls.dm +++ b/code/game/objects/structures/false_walls.dm @@ -75,11 +75,14 @@ icon = 'icons/turf/walls.dmi' var/mineral = "metal" var/walltype = "metal" + var/walltype2 = "rwall" // So it also connects with rwalls, like regular walls do var/opening = 0 density = 1 opacity = 1 /obj/structure/falsewall/New() + if(!walltype2) + walltype2 = walltype relativewall_neighbours() ..() @@ -105,11 +108,11 @@ for(var/turf/simulated/wall/W in orange(src,1)) if(abs(src.x-W.x)-abs(src.y-W.y)) //doesn't count diagonal walls - if(walltype == W.walltype)//Only 'like' walls connect -Sieve + if(walltype == W.walltype || walltype2 == W.walltype)//Only 'like' walls connect -Sieve junction |= get_dir(src,W) for(var/obj/structure/falsewall/W in orange(src,1)) if(abs(src.x-W.x)-abs(src.y-W.y)) //doesn't count diagonal walls - if(walltype == W.walltype) + if(walltype == W.walltype || walltype2 == W.walltype) junction |= get_dir(src,W) icon_state = "[walltype][junction]" return @@ -162,7 +165,7 @@ qdel(src) return T -/obj/structure/falsewall/attackby(obj/item/weapon/W, mob/user) +/obj/structure/falsewall/attackby(obj/item/weapon/W, mob/user, params) if(opening) user << "You must wait until the door has stopped moving." return @@ -213,6 +216,8 @@ name = "reinforced wall" desc = "A huge chunk of reinforced metal used to seperate rooms." icon_state = "r_wall" + walltype = "rwall" + walltype2 = "metal" /obj/structure/falsewall/reinforced/ChangeToWall(delete = 1) var/turf/T = get_turf(src) @@ -244,11 +249,11 @@ for(var/turf/simulated/wall/W in orange(src,1)) if(abs(src.x-W.x)-abs(src.y-W.y)) //doesn't count diagonal walls - if(src.walltype == W.walltype)//Only 'like' walls connect -Sieve + if(src.walltype == W.walltype || walltype2 == W.walltype)//Only 'like' walls connect -Sieve junction |= get_dir(src,W) for(var/obj/structure/falsewall/W in orange(src,1)) if(abs(src.x-W.x)-abs(src.y-W.y)) //doesn't count diagonal walls - if(src.walltype == W.walltype) + if(src.walltype == W.walltype || src.walltype2 == W.walltype) junction |= get_dir(src,W) icon_state = "rwall[junction]" return @@ -266,7 +271,7 @@ var/active = null var/last_event = 0 -/obj/structure/falsewall/uranium/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/falsewall/uranium/attackby(obj/item/weapon/W as obj, mob/user as mob, params) radiate() ..() diff --git a/code/game/objects/structures/foodcart.dm b/code/game/objects/structures/foodcart.dm new file mode 100644 index 00000000000..c1a3a388d48 --- /dev/null +++ b/code/game/objects/structures/foodcart.dm @@ -0,0 +1,204 @@ +/obj/structure/foodcart + name = "food cart" + desc = "A cart for transporting food and drinks." + icon = 'icons/obj/foodcart.dmi' + icon_state = "cart" + anchored = 0 + density = 1 + //Food slots + var/list/food_slots[6] + //var/obj/item/weapon/reagent_containers/food/snacks/food1 = null + //var/obj/item/weapon/reagent_containers/food/snacks/food2 = null + //var/obj/item/weapon/reagent_containers/food/snacks/food3 = null + //var/obj/item/weapon/reagent_containers/food/snacks/food4 = null + //var/obj/item/weapon/reagent_containers/food/snacks/food5 = null + //var/obj/item/weapon/reagent_containers/food/snacks/food6 = null + //Drink slots + var/list/drink_slots[6] + //var/obj/item/weapon/reagent_containers/food/drinks/drink1 = null + //var/obj/item/weapon/reagent_containers/food/drinks/drink2 = null + //var/obj/item/weapon/reagent_containers/food/drinks/drink3 = null + //var/obj/item/weapon/reagent_containers/food/drinks/drink4 = null + //var/obj/item/weapon/reagent_containers/food/drinks/drink5 = null + //var/obj/item/weapon/reagent_containers/food/drinks/drink6 = null + +/obj/structure/foodcart/proc/put_in_cart(obj/item/I, mob/user) + user.drop_item() + I.loc = src + updateUsrDialog() + user << "You put [I] into [src]." + return + +/obj/structure/foodcart/attackby(obj/item/I, mob/user, params) + var/fail_msg = "There are no open spaces for this in [src]." + if(!I.is_robot_module()) + if(istype(I, /obj/item/weapon/reagent_containers/food/snacks)) + var/success = 0 + for(var/s=1,s<=6,s++) + if(!food_slots[s]) + put_in_cart(I, user) + food_slots[s]=I + update_icon() + success = 1 + break; + if(!success) + user << fail_msg + else if(istype(I, /obj/item/weapon/reagent_containers/food/drinks)) + var/success = 0 + for(var/s=1,s<=6,s++) + if(!drink_slots[s]) + put_in_cart(I, user) + drink_slots[s]=I + update_icon() + success = 1 + break; + if(!success) + user << fail_msg + else if(istype(I, /obj/item/weapon/wrench)) + if (!anchored && !isinspace()) + playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) + user.visible_message( \ + "[user] tightens \the [src]'s casters.", \ + " You have tightened \the [src]'s casters.", \ + "You hear ratchet.") + anchored = 1 + else if(anchored) + playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) + user.visible_message( \ + "[user] loosens \the [src]'s casters.", \ + " You have loosened \the [src]'s casters.", \ + "You hear ratchet.") + anchored = 0 + else + usr << "You cannot interface your modules [src]!" + +/obj/structure/foodcart/attack_hand(mob/user) + user.set_machine(src) + var/dat + if(food_slots[1]) + dat += "[food_slots[1]]
    " + if(food_slots[2]) + dat += "[food_slots[2]]
    " + if(food_slots[3]) + dat += "[food_slots[3]]
    " + if(food_slots[4]) + dat += "[food_slots[4]]
    " + if(food_slots[5]) + dat += "[food_slots[5]]
    " + if(food_slots[6]) + dat += "[food_slots[6]]
    " + if(drink_slots[1]) + dat += "[drink_slots[1]]
    " + if(drink_slots[2]) + dat += "[drink_slots[2]]
    " + if(drink_slots[3]) + dat += "[drink_slots[3]]
    " + if(drink_slots[4]) + dat += "[drink_slots[4]]
    " + if(drink_slots[5]) + dat += "[drink_slots[5]]
    " + if(drink_slots[6]) + dat += "[drink_slots[6]]
    " + var/datum/browser/popup = new(user, "foodcart", name, 240, 160) + popup.set_content(dat) + popup.open() + +/obj/structure/foodcart/Topic(href, href_list) + if(!in_range(src, usr)) + return + if(!isliving(usr)) + return + var/mob/living/user = usr + if(href_list["f1"]) + if(food_slots[1]) + user.put_in_hands(food_slots[1]) + user << "You take [food_slots[1]] from [src]." + food_slots[1] = null + if(href_list["f2"]) + if(food_slots[2]) + user.put_in_hands(food_slots[2]) + user << "You take [food_slots[2]] from [src]." + food_slots[2] = null + if(href_list["f3"]) + if(food_slots[3]) + user.put_in_hands(food_slots[3]) + user << "You take [food_slots[3]] from [src]." + food_slots[3] = null + if(href_list["f4"]) + if(food_slots[4]) + user.put_in_hands(food_slots[4]) + user << "You take [food_slots[4]] from [src]." + food_slots[4] = null + if(href_list["f5"]) + if(food_slots[5]) + user.put_in_hands(food_slots[5]) + user << "You take [food_slots[5]] from [src]." + food_slots[5] = null + if(href_list["f6"]) + if(food_slots[6]) + user.put_in_hands(food_slots[6]) + user << "You take [food_slots[6]] from [src]." + food_slots[6] = null + if(href_list["d1"]) + if(drink_slots[1]) + user.put_in_hands(drink_slots[1]) + user << "You take [drink_slots[1]] from [src]." + drink_slots[1] = null + if(href_list["d2"]) + if(drink_slots[2]) + user.put_in_hands(drink_slots[2]) + user << "You take [drink_slots[2]] from [src]." + drink_slots[2] = null + if(href_list["d3"]) + if(drink_slots[3]) + user.put_in_hands(drink_slots[3]) + user << "You take [drink_slots[3]] from [src]." + drink_slots[3] = null + if(href_list["d4"]) + if(drink_slots[4]) + user.put_in_hands(drink_slots[4]) + user << "You take [drink_slots[4]] from [src]." + drink_slots[4] = null + if(href_list["d5"]) + if(drink_slots[5]) + user.put_in_hands(drink_slots[5]) + user << "You take [drink_slots[5]] from [src]." + drink_slots[5] = null + if(href_list["d6"]) + if(drink_slots[6]) + user.put_in_hands(drink_slots[6]) + user << "You take [drink_slots[6]] from [src]." + drink_slots[6] = null + + update_icon() //Not really needed without overlays, but keeping just in case + updateUsrDialog() + +/* +Overlays for cart_unused +/obj/structure/foodcart/update_icon() + overlays = null + if(food1) + overlays += "cart_food1" + if(food2) + overlays += "cart_food2" + if(food3) + overlays += "cart_food3" + if(food4) + overlays += "cart_food4" + if(food5) + overlays += "cart_food5" + if(food6) + overlays += "cart_food6" + if(drink1) + overlays += "cart_drink1" + if(drink2) + overlays += "cart_drink2" + if(drink3) + overlays += "cart_drink3" + if(drink4) + overlays += "cart_drink4" + if(drink5) + overlays += "cart_drink5" + if(drink6) + overlays += "cart_drink6" +*/ \ No newline at end of file diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index d8e22940639..f5a2e615b6a 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -4,151 +4,83 @@ density = 1 layer = 2 var/state = 0 + var/health = 200 - attackby(obj/item/W as obj, mob/user as mob) - if(istype(W, /obj/item/weapon/wrench) && state == 0) - if(anchored && !istype(src,/obj/structure/girder/displaced)) - playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1) - user << "\blue Now disassembling the girder" - if(do_after(user,40)) - if(!src) return - user << "\blue You dissasembled the girder!" - new /obj/item/stack/sheet/metal(get_turf(src)) - del(src) - else if(!anchored) - playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1) - user << "\blue Now securing the girder" - if(get_turf(user, 40)) - user << "\blue You secured the girder!" - new/obj/structure/girder( src.loc ) - del(src) - - else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter)) - user << "\blue Now slicing apart the girder" - if(do_after(user,30)) +/obj/structure/girder/attackby(obj/item/W as obj, mob/user as mob, params) + if(istype(W, /obj/item/weapon/wrench) && state == 0) + if(anchored && !istype(src,/obj/structure/girder/displaced)) + playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1) + user << "\blue Now disassembling the girder" + if(do_after(user,40)) if(!src) return - user << "\blue You slice apart the girder!" + user << "\blue You dissasembled the girder!" new /obj/item/stack/sheet/metal(get_turf(src)) del(src) - - else if(istype(W, /obj/item/weapon/pickaxe/diamonddrill)) - user << "\blue You drill through the girder!" - new /obj/item/stack/sheet/metal(get_turf(src)) - del(src) - - else if(istype(W, /obj/item/weapon/screwdriver) && state == 2 && istype(src,/obj/structure/girder/reinforced)) - playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1) - user << "\blue Now unsecuring support struts" - if(do_after(user,40)) - if(!src) return - user << "\blue You unsecured the support struts!" - state = 1 - - else if(istype(W, /obj/item/weapon/wirecutters) && istype(src,/obj/structure/girder/reinforced) && state == 1) - playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1) - user << "\blue Now removing support struts" - if(do_after(user,40)) - if(!src) return - user << "\blue You removed the support struts!" + else if(!anchored) + playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1) + user << "\blue Now securing the girder" + if(get_turf(user, 40)) + user << "\blue You secured the girder!" new/obj/structure/girder( src.loc ) del(src) - else if(istype(W, /obj/item/weapon/crowbar) && state == 0 && anchored ) - playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1) - user << "\blue Now dislodging the girder" - if(do_after(user, 40)) - if(!src) return - user << "\blue You dislodged the girder!" - new/obj/structure/girder/displaced( src.loc ) - del(src) + else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter)) + user << "\blue Now slicing apart the girder" + if(do_after(user,30)) + if(!src) return + user << "\blue You slice apart the girder!" + new /obj/item/stack/sheet/metal(get_turf(src)) + del(src) - else if(istype(W, /obj/item/stack/sheet)) + else if(istype(W, /obj/item/weapon/pickaxe/diamonddrill)) + user << "\blue You drill through the girder!" + new /obj/item/stack/sheet/metal(get_turf(src)) + del(src) - var/obj/item/stack/sheet/S = W - switch(S.type) + else if(istype(W, /obj/item/weapon/screwdriver) && state == 2 && istype(src,/obj/structure/girder/reinforced)) + playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1) + user << "\blue Now unsecuring support struts" + if(do_after(user,40)) + if(!src) return + user << "\blue You unsecured the support struts!" + state = 1 - if(/obj/item/stack/sheet/metal, /obj/item/stack/sheet/metal/cyborg) - if(!anchored) - if(S.amount < 2) return - var/pdiff=performWallPressureCheck(src.loc) - if(!pdiff) - S.use(2) - user << "\blue You create a false wall! Push on it to open or close the passage." - new /obj/structure/falsewall (src.loc) - del(src) - else - user << "\red There is too much air moving through the gap! The door wouldn't stay closed if you built it." - message_admins("Attempted false wall made by [user.real_name] ([formatPlayerPanel(user,user.ckey)]) at [formatJumpTo(loc)] had a pressure difference of [pdiff]!") - log_admin("Attempted false wall made by [user.real_name] (user.ckey) at [loc] had a pressure difference of [pdiff]!") - return - else - if(S.amount < 2) return ..() - user << "\blue Now adding plating..." - if (do_after(user,40)) - if(!src || !S || S.amount < 2) return - S.use(2) - user << "\blue You added the plating!" - var/turf/Tsrc = get_turf(src) - Tsrc.ChangeTurf(/turf/simulated/wall) - for(var/turf/simulated/wall/X in Tsrc.loc) - if(X) X.add_hiddenprint(usr) - del(src) - return + else if(istype(W, /obj/item/weapon/wirecutters) && istype(src,/obj/structure/girder/reinforced) && state == 1) + playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1) + user << "\blue Now removing support struts" + if(do_after(user,40)) + if(!src) return + user << "\blue You removed the support struts!" + new/obj/structure/girder( src.loc ) + del(src) - if(/obj/item/stack/sheet/plasteel) - if(!anchored) - if(S.amount < 2) return - var/pdiff=performWallPressureCheck(src.loc) - if(!pdiff) - S.use(2) - user << "\blue You create a false wall! Push on it to open or close the passage." - new /obj/structure/falsewall/reinforced (src.loc) - del(src) - else - user << "\red There is too much air moving through the gap! The door wouldn't stay closed if you built it." - message_admins("Attempted false rwall made by [user.real_name] ([formatPlayerPanel(user,user.ckey)]) at [formatJumpTo(loc)] had a pressure difference of [pdiff]!") - log_admin("Attempted false rwall made by [user.real_name] ([user.ckey]) at [loc] had a pressure difference of [pdiff]!") - return - else - if (src.icon_state == "reinforced") //I cant believe someone would actually write this line of code... - if(S.amount < 1) return ..() - user << "\blue Now finalising reinforced wall." - if(do_after(user, 50)) - if(!src || !S || S.amount < 1) return - S.use(1) - user << "\blue Wall fully reinforced!" - var/turf/Tsrc = get_turf(src) - Tsrc.ChangeTurf(/turf/simulated/wall/r_wall) - for(var/turf/simulated/wall/r_wall/X in Tsrc.loc) - if(X) X.add_hiddenprint(usr) - del(src) - return - else - if(S.amount < 1) return ..() - user << "\blue Now reinforcing girders" - if (do_after(user,60)) - if(!src || !S || S.amount < 1) return - S.use(1) - user << "\blue Girders reinforced!" - new/obj/structure/girder/reinforced( src.loc ) - del(src) - return + else if(istype(W, /obj/item/weapon/crowbar) && state == 0 && anchored ) + playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1) + user << "\blue Now dislodging the girder" + if(do_after(user, 40)) + if(!src) return + user << "\blue You dislodged the girder!" + new/obj/structure/girder/displaced( src.loc ) + del(src) - if(S.sheettype) - var/M = S.sheettype + else if(istype(W, /obj/item/stack/sheet)) + + var/obj/item/stack/sheet/S = W + switch(S.type) + + if(/obj/item/stack/sheet/metal, /obj/item/stack/sheet/metal/cyborg) if(!anchored) if(S.amount < 2) return var/pdiff=performWallPressureCheck(src.loc) if(!pdiff) S.use(2) user << "\blue You create a false wall! Push on it to open or close the passage." - var/F = text2path("/obj/structure/falsewall/[M]") - new F (src.loc) + new /obj/structure/falsewall (src.loc) del(src) else user << "\red There is too much air moving through the gap! The door wouldn't stay closed if you built it." - message_admins("Attempted false [M] wall made by [user.real_name] ([formatPlayerPanel(user,user.ckey)]) at [formatJumpTo(loc)] had a pressure difference of [pdiff]!") - log_admin("Attempted false [M] wall made by [user.real_name] ([user.ckey]) at [loc] had a pressure difference of [pdiff]!") + message_admins("Attempted false wall made by [user.real_name] ([formatPlayerPanel(user,user.ckey)]) at [formatJumpTo(loc)] had a pressure difference of [pdiff]!") + log_admin("Attempted false wall made by [user.real_name] (user.ckey) at [loc] had a pressure difference of [pdiff]!") return else if(S.amount < 2) return ..() @@ -158,67 +90,138 @@ S.use(2) user << "\blue You added the plating!" var/turf/Tsrc = get_turf(src) - Tsrc.ChangeTurf(text2path("/turf/simulated/wall/mineral/[M]")) - for(var/turf/simulated/wall/mineral/X in Tsrc.loc) + Tsrc.ChangeTurf(/turf/simulated/wall) + for(var/turf/simulated/wall/X in Tsrc.loc) if(X) X.add_hiddenprint(usr) del(src) return - add_hiddenprint(usr) + if(/obj/item/stack/sheet/plasteel) + if(!anchored) + if(S.amount < 2) return + var/pdiff=performWallPressureCheck(src.loc) + if(!pdiff) + S.use(2) + user << "\blue You create a false wall! Push on it to open or close the passage." + new /obj/structure/falsewall/reinforced (src.loc) + del(src) + else + user << "\red There is too much air moving through the gap! The door wouldn't stay closed if you built it." + message_admins("Attempted false rwall made by [user.real_name] ([formatPlayerPanel(user,user.ckey)]) at [formatJumpTo(loc)] had a pressure difference of [pdiff]!") + log_admin("Attempted false rwall made by [user.real_name] ([user.ckey]) at [loc] had a pressure difference of [pdiff]!") + return + else + if (src.icon_state == "reinforced") //I cant believe someone would actually write this line of code... + if(S.amount < 1) return ..() + user << "\blue Now finalising reinforced wall." + if(do_after(user, 50)) + if(!src || !S || S.amount < 1) return + S.use(1) + user << "\blue Wall fully reinforced!" + var/turf/Tsrc = get_turf(src) + Tsrc.ChangeTurf(/turf/simulated/wall/r_wall) + for(var/turf/simulated/wall/r_wall/X in Tsrc.loc) + if(X) X.add_hiddenprint(usr) + del(src) + return + else + if(S.amount < 1) return ..() + user << "\blue Now reinforcing girders" + if (do_after(user,60)) + if(!src || !S || S.amount < 1) return + S.use(1) + user << "\blue Girders reinforced!" + new/obj/structure/girder/reinforced( src.loc ) + del(src) + return - else if(istype(W, /obj/item/pipe)) - var/obj/item/pipe/P = W - if (P.pipe_type in list(0, 1, 5)) //simple pipes, simple bends, and simple manifolds. - user.drop_item() - P.loc = src.loc - user << "\blue You fit the pipe into the [src]!" - else - ..() - - - bullet_act(var/obj/item/projectile/Proj) - if(istype(Proj ,/obj/item/projectile/beam/pulse)) - src.ex_act(2) - ..() - return 0 - - blob_act() - if(prob(40)) - del(src) - - bullet_act(var/obj/item/projectile/Proj) - if(istype(Proj ,/obj/item/projectile/beam/pulse)) - src.ex_act(2) - ..() - return 0 - - ex_act(severity) - switch(severity) - if(1.0) - qdel(src) - return - if(2.0) - if (prob(75)) - var/remains = pick(/obj/item/stack/rods,/obj/item/stack/sheet/metal) - new remains(loc) - qdel(src) - return - if(3.0) - if (prob(30)) - var/remains = pick(/obj/item/stack/rods,/obj/item/stack/sheet/metal) - new remains(loc) - qdel(src) - return + if(S.sheettype) + var/M = S.sheettype + if(!anchored) + if(S.amount < 2) return + var/pdiff=performWallPressureCheck(src.loc) + if(!pdiff) + S.use(2) + user << "\blue You create a false wall! Push on it to open or close the passage." + var/F = text2path("/obj/structure/falsewall/[M]") + new F (src.loc) + del(src) + else + user << "\red There is too much air moving through the gap! The door wouldn't stay closed if you built it." + message_admins("Attempted false [M] wall made by [user.real_name] ([formatPlayerPanel(user,user.ckey)]) at [formatJumpTo(loc)] had a pressure difference of [pdiff]!") + log_admin("Attempted false [M] wall made by [user.real_name] ([user.ckey]) at [loc] had a pressure difference of [pdiff]!") + return else - return + if(S.amount < 2) return ..() + user << "\blue Now adding plating..." + if (do_after(user,40)) + if(!src || !S || S.amount < 2) return + S.use(2) + user << "\blue You added the plating!" + var/turf/Tsrc = get_turf(src) + Tsrc.ChangeTurf(text2path("/turf/simulated/wall/mineral/[M]")) + for(var/turf/simulated/wall/mineral/X in Tsrc.loc) + if(X) X.add_hiddenprint(usr) + del(src) + return + + add_hiddenprint(usr) + + else if(istype(W, /obj/item/pipe)) + var/obj/item/pipe/P = W + if (P.pipe_type in list(0, 1, 5)) //simple pipes, simple bends, and simple manifolds. + user.drop_item() + P.loc = src.loc + user << "\blue You fit the pipe into the [src]!" + else + ..() + +/obj/structure/girder/blob_act() + if(prob(40)) + del(src) + +/obj/structure/girder/bullet_act(var/obj/item/projectile/Proj) + if(istype(Proj, /obj/item/projectile/beam)) + health -= Proj.damage + ..() + if(health <= 0) + new /obj/item/stack/sheet/metal(get_turf(src)) + del(src) + + if(istype(Proj ,/obj/item/projectile/beam/pulse)) + src.ex_act(2) + ..() + return 0 + +/obj/structure/girder/ex_act(severity) + switch(severity) + if(1.0) + qdel(src) + return + if(2.0) + if (prob(75)) + var/remains = pick(/obj/item/stack/rods,/obj/item/stack/sheet/metal) + new remains(loc) + qdel(src) + return + if(3.0) + if (prob(30)) + var/remains = pick(/obj/item/stack/rods,/obj/item/stack/sheet/metal) + new remains(loc) + qdel(src) + return + else + return /obj/structure/girder/displaced icon_state = "displaced" anchored = 0 + health = 50 /obj/structure/girder/reinforced icon_state = "reinforced" state = 2 + health = 500 /obj/structure/cultgirder icon= 'icons/obj/cult.dmi' @@ -226,47 +229,55 @@ anchored = 1 density = 1 layer = 2 + var/health = 250 - attackby(obj/item/W as obj, mob/user as mob) - if(istype(W, /obj/item/weapon/wrench)) - playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1) - user << "\blue Now disassembling the girder" - if(do_after(user,40)) - user << "\blue You dissasembled the girder!" - new /obj/effect/decal/remains/human(get_turf(src)) - del(src) +/obj/structure/cultgirder/attackby(obj/item/W as obj, mob/user as mob, params) + if(istype(W, /obj/item/weapon/wrench)) + playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1) + user << "\blue Now disassembling the girder" + if(do_after(user,40)) + user << "\blue You dissasembled the girder!" + dismantle() - else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter)) - user << "\blue Now slicing apart the girder" - if(do_after(user,30)) - user << "\blue You slice apart the girder!" - new /obj/effect/decal/remains/human(get_turf(src)) - del(src) + else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter)) + user << "\blue Now slicing apart the girder" + if(do_after(user,30)) + user << "\blue You slice apart the girder!" + dismantle() - else if(istype(W, /obj/item/weapon/pickaxe/diamonddrill)) - user << "\blue You drill through the girder!" - new /obj/effect/decal/remains/human(get_turf(src)) - del(src) + else if(istype(W, /obj/item/weapon/pickaxe/diamonddrill)) + user << "\blue You drill through the girder!" + dismantle() + +/obj/structure/cultgirder/proc/dismantle() + new /obj/effect/decal/remains/human(get_turf(src)) + qdel(src) - blob_act() - if(prob(40)) - del(src) +/obj/structure/cultgirder/blob_act() + if(prob(40)) + dismantle() + +/obj/structure/cultgirder/bullet_act(var/obj/item/projectile/Proj) //No beam check- How else will you destroy the cult girder with silver bullets????? + health -= Proj.damage + ..() + if(health <= 0) + dismantle() + return - - ex_act(severity) - switch(severity) - if(1.0) +/obj/structure/cultgirder/ex_act(severity) + switch(severity) + if(1.0) + qdel(src) + return + if(2.0) + if (prob(30)) + new /obj/effect/decal/remains/human(loc) qdel(src) - return - if(2.0) - if (prob(30)) - new /obj/effect/decal/remains/human(loc) - qdel(src) - return - if(3.0) - if (prob(5)) - new /obj/effect/decal/remains/human(loc) - qdel(src) - return - else - return \ No newline at end of file + return + if(3.0) + if (prob(5)) + new /obj/effect/decal/remains/human(loc) + qdel(src) + return + else + return \ No newline at end of file diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index b02fb0f0c86..c5114cf2ef9 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -5,7 +5,7 @@ icon_state = "grille" density = 1 anchored = 1 - flags = FPRINT | CONDUCT + flags = CONDUCT pressure_resistance = 5*ONE_ATMOSPHERE layer = 2.9 explosion_resistance = 5 @@ -55,10 +55,12 @@ if(ismob(user)) shock(user, 70) -/obj/structure/grille/attack_paw(mob/user as mob) +/obj/structure/grille/attack_paw(mob/living/user as mob) attack_hand(user) -/obj/structure/grille/attack_hand(mob/user as mob) +/obj/structure/grille/attack_hand(mob/living/user as mob) + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) playsound(loc, 'sound/effects/grillehit.ogg', 80, 1) user.visible_message("[user] kicks [src].", \ "You kick [src].", \ @@ -66,15 +68,16 @@ if(shock(user, 70)) return - if(M_HULK in user.mutations) + if(HULK in user.mutations) health -= 5 else health -= 1 healthcheck() -/obj/structure/grille/attack_alien(mob/user as mob) +/obj/structure/grille/attack_alien(mob/living/user as mob) if(istype(user, /mob/living/carbon/alien/larva)) return - + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) playsound(loc, 'sound/effects/grillehit.ogg', 80, 1) user.visible_message("[user] mangles [src].", \ "You mangle [src].", \ @@ -85,7 +88,9 @@ healthcheck() return -/obj/structure/grille/attack_slime(mob/user as mob) +/obj/structure/grille/attack_slime(mob/living/user as mob) + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) var/mob/living/carbon/slime/S = user if (!S.is_adult) return @@ -101,7 +106,8 @@ /obj/structure/grille/attack_animal(var/mob/living/simple_animal/M as mob) if(M.melee_damage_upper == 0) return - + M.changeNext_move(CLICK_CD_MELEE) + M.do_attack_animation(src) playsound(loc, 'sound/effects/grillehit.ogg', 80, 1) M.visible_message("[M] smashes against [src].", \ "You smash against [src].", \ @@ -136,7 +142,8 @@ healthcheck() return -/obj/structure/grille/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/grille/attackby(obj/item/weapon/W as obj, mob/user as mob, params) + user.changeNext_move(CLICK_CD_MELEE) if(iswirecutter(W)) if(!shock(user, 100)) playsound(loc, 'sound/items/Wirecutter.ogg', 100, 1) diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm index 8422c076d76..3cb32653054 100644 --- a/code/game/objects/structures/inflatable.dm +++ b/code/game/objects/structures/inflatable.dm @@ -34,14 +34,6 @@ update_nearby_tiles() ..() - proc/update_nearby_tiles(need_rebuild) //Copypasta from airlock code - if(!air_master) - return 0 - air_master.mark_for_update(get_turf(src)) - return 1 - - - CanPass(atom/movable/mover, turf/target, height=0, air_group=0) return 0 @@ -109,7 +101,7 @@ attack_generic(user, rand(10, 15)) - attackby(obj/item/weapon/W as obj, mob/user as mob) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(!istype(W)) return if (can_puncture(W)) diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index 9ca2d7cbdb4..cc7e50bf888 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -38,7 +38,7 @@ if((INFINITY * -1) to 0) usr << "It appears completely unsalvageable" -/obj/structure/stool/bed/chair/cart/attackby(obj/item/W, mob/user) +/obj/structure/stool/bed/chair/cart/attackby(obj/item/W, mob/user, params) if (istype(W, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/WT = W if (WT.remove_fuel(0)) @@ -287,7 +287,7 @@ if(mybag) usr << "\A [mybag] is hanging on the [name]." -/obj/structure/stool/bed/chair/cart/janicart/attackby(obj/item/W, mob/user) +/obj/structure/stool/bed/chair/cart/janicart/attackby(obj/item/W, mob/user, params) ..() if(istype(W, /obj/item/weapon/mop)) if(reagents.total_volume >= 2) @@ -442,7 +442,7 @@ return -/obj/structure/janitorialcart/attackby(obj/item/I, mob/user) +/obj/structure/janitorialcart/attackby(obj/item/I, mob/user, params) var/fail_msg = "There is already one of those in [src]." if(!I.is_robot_module()) @@ -482,14 +482,29 @@ update_icon() else user << "[src] can't hold any more signs." - else if(mybag) - mybag.attackby(I, user) else if(istype(I, /obj/item/weapon/crowbar)) user.visible_message("[user] begins to empty the contents of [src].") if(do_after(user, 30)) usr << "You empty the contents of [src]'s bucket onto the floor." reagents.reaction(src.loc) src.reagents.clear_reagents() + else if(istype(I, /obj/item/weapon/wrench)) + if (!anchored && !isinspace()) + playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) + user.visible_message( \ + "[user] tightens \the [src]'s casters.", \ + " You have tightened \the [src]'s casters.", \ + "You hear ratchet.") + anchored = 1 + else if(anchored) + playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) + user.visible_message( \ + "[user] loosens \the [src]'s casters.", \ + " You have loosened \the [src]'s casters.", \ + "You hear ratchet.") + anchored = 0 + else if(mybag) + mybag.attackby(I, user, params) else usr << "You cannot interface your modules [src]!" diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm index f0060dfe935..eb3f0a3c371 100644 --- a/code/game/objects/structures/kitchen_spike.dm +++ b/code/game/objects/structures/kitchen_spike.dm @@ -15,7 +15,7 @@ attack_paw(mob/user as mob) return src.attack_hand(usr) - attackby(obj/item/weapon/grab/G as obj, mob/user as mob) + attackby(obj/item/weapon/grab/G as obj, mob/user as mob, params) if(!istype(G, /obj/item/weapon/grab)) return if(istype(G.affecting, /mob/living/carbon/monkey)) diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm index a10448cfcc4..dfcb2f58270 100644 --- a/code/game/objects/structures/ladders.dm +++ b/code/game/objects/structures/ladders.dm @@ -69,5 +69,5 @@ /obj/structure/ladder/attack_paw(mob/user as mob) return attack_hand(user) -/obj/structure/ladder/attackby(obj/item/weapon/W, mob/user as mob) +/obj/structure/ladder/attackby(obj/item/weapon/W, mob/user as mob, params) return attack_hand(user) \ No newline at end of file diff --git a/code/game/objects/structures/lamarr_cage.dm b/code/game/objects/structures/lamarr_cage.dm index bd870f68341..5b6acef00ec 100644 --- a/code/game/objects/structures/lamarr_cage.dm +++ b/code/game/objects/structures/lamarr_cage.dm @@ -66,7 +66,7 @@ return -/obj/structure/lamarr/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/lamarr/attackby(obj/item/weapon/W as obj, mob/user as mob, params) src.health -= W.force src.healthcheck() ..() diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index 4faf0d28596..ef8d3dd15e4 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -49,7 +49,7 @@ else return -/obj/structure/lattice/attackby(obj/item/C as obj, mob/user as mob) +/obj/structure/lattice/attackby(obj/item/C as obj, mob/user as mob, params) if (istype(C, /obj/item/stack/tile/plasteel) || istype(C, /obj/item/stack/rods)) var/turf/T = get_turf(src) diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index 8b7d70b4dc4..a022c1c722b 100644 --- a/code/game/objects/structures/mineral_doors.dm +++ b/code/game/objects/structures/mineral_doors.dm @@ -102,7 +102,7 @@ else icon_state = mineralType - attackby(obj/item/weapon/W as obj, mob/user as mob) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/pickaxe)) var/obj/item/weapon/pickaxe/digTool = W user << "You start digging the [name]." @@ -157,13 +157,6 @@ CheckHardness() return - proc/update_nearby_tiles(need_rebuild) //Copypasta from airlock code - if(!air_master) return 0 - - air_master.mark_for_update(get_turf(src)) - - return 1 - /obj/structure/mineral_door/iron mineralType = "metal" hardness = 3 @@ -194,7 +187,7 @@ /obj/structure/mineral_door/transparent/plasma mineralType = "plasma" - attackby(obj/item/weapon/W as obj, mob/user as mob) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/WT = W if(WT.remove_fuel(0, user)) diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index 59771219737..e32c879b304 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -71,7 +71,8 @@ ..() -/obj/structure/mirror/attackby(obj/item/I as obj, mob/user as mob) +/obj/structure/mirror/attackby(obj/item/I as obj, mob/living/user as mob, params) + user.do_attack_animation(src) if(shattered) playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) return @@ -84,8 +85,9 @@ playsound(src.loc, 'sound/effects/Glasshit.ogg', 70, 1) -/obj/structure/mirror/attack_alien(mob/user as mob) +/obj/structure/mirror/attack_alien(mob/living/user as mob) if(islarva(user)) return + user.do_attack_animation(src) if(shattered) playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) return @@ -93,10 +95,11 @@ shatter() -/obj/structure/mirror/attack_animal(mob/user as mob) +/obj/structure/mirror/attack_animal(mob/living/user as mob) if(!isanimal(user)) return var/mob/living/simple_animal/M = user if(M.melee_damage_upper <= 0) return + M.do_attack_animation(src) if(shattered) playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) return @@ -104,10 +107,11 @@ shatter() -/obj/structure/mirror/attack_slime(mob/user as mob) +/obj/structure/mirror/attack_slime(mob/living/user as mob) var/mob/living/carbon/slime/S = user if (!S.is_adult) return + user.do_attack_animation(src) if(shattered) playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) return diff --git a/code/game/objects/structures/mop_bucket.dm b/code/game/objects/structures/mop_bucket.dm index b27f8853904..9c25217d603 100644 --- a/code/game/objects/structures/mop_bucket.dm +++ b/code/game/objects/structures/mop_bucket.dm @@ -5,7 +5,7 @@ icon_state = "mopbucket" density = 1 pressure_resistance = 5 - flags = FPRINT | TABLEPASS | OPENCONTAINER + flags = OPENCONTAINER var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite /obj/structure/mopbucket/New() @@ -19,7 +19,7 @@ usr << text("\icon[] [] contains [] units of water left!", src, src.name, src.reagents.total_volume) ..() -/obj/structure/mopbucket/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/mopbucket/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/mop)) if (src.reagents.total_volume >= 2) src.reagents.trans_to(W, 2) diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 1b0825f4f84..c591c75b0e3 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -104,14 +104,14 @@ update() return -/obj/structure/morgue/attackby(P as obj, mob/user as mob) +/obj/structure/morgue/attackby(P as obj, mob/user as mob, params) if (istype(P, /obj/item/weapon/pen)) var/t = input(user, "What would you like the label to be?", text("[]", src.name), null) as text if (user.get_active_hand() != P) return if ((!in_range(src, usr) && src.loc != user)) return - t = copytext(sanitize(t),1,MAX_MESSAGE_LEN) + t = sanitize(copytext(t,1,MAX_MESSAGE_LEN)) if (t) src.name = text("Morgue- '[]'", t) src.overlays += image(src.icon, "morgue_label") @@ -278,14 +278,14 @@ src.add_fingerprint(user) update() -/obj/structure/crematorium/attackby(P as obj, mob/user as mob) +/obj/structure/crematorium/attackby(P as obj, mob/user as mob, params) if (istype(P, /obj/item/weapon/pen)) var/t = input(user, "What would you like the label to be?", text("[]", src.name), null) as text if (user.get_active_hand() != P) return if ((!in_range(src, usr) > 1 && src.loc != user)) return - t = copytext(sanitize(t),1,MAX_MESSAGE_LEN) + t = sanitize(copytext(t,1,MAX_MESSAGE_LEN)) if (t) src.name = text("Crematorium- '[]'", t) else diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm index 733ff964466..6ed7da87a3b 100644 --- a/code/game/objects/structures/musician.dm +++ b/code/game/objects/structures/musician.dm @@ -19,7 +19,7 @@ instrumentDir = dir instrumentObj = obj -/datum/song/proc/Destroy() +/datum/song/Destroy() instrumentObj = null return @@ -332,7 +332,7 @@ user.set_machine(src) song.interact(user) -/obj/structure/piano/attackby(obj/item/O as obj, mob/user as mob) +/obj/structure/piano/attackby(obj/item/O as obj, mob/user as mob, params) if (istype(O, /obj/item/weapon/wrench)) if (!anchored && !isinspace()) playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm index 1f23e10411d..d5997adfda9 100644 --- a/code/game/objects/structures/noticeboard.dm +++ b/code/game/objects/structures/noticeboard.dm @@ -3,7 +3,6 @@ desc = "A board for pinning important notices upon." icon = 'icons/obj/stationobjs.dmi' icon_state = "nboard00" - flags = FPRINT density = 0 anchored = 1 var/notices = 0 @@ -17,7 +16,7 @@ icon_state = "nboard0[notices]" //attaching papers!! -/obj/structure/noticeboard/attackby(var/obj/item/weapon/O as obj, var/mob/user as mob) +/obj/structure/noticeboard/attackby(var/obj/item/weapon/O as obj, var/mob/user as mob, params) if(istype(O, /obj/item/weapon/paper)) if(notices < 5) O.add_fingerprint(user) diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm index 00946b8678c..d665589182e 100644 --- a/code/game/objects/structures/safe.dm +++ b/code/game/objects/structures/safe.dm @@ -90,7 +90,7 @@ FLOOR SAFES var/mob/living/carbon/human/user = usr var/canhear = 0 - if(istype(user.l_hand, /obj/item/clothing/tie/stethoscope) || istype(user.r_hand, /obj/item/clothing/tie/stethoscope)) + if(istype(user.l_hand, /obj/item/clothing/accessory/stethoscope) || istype(user.r_hand, /obj/item/clothing/accessory/stethoscope)) canhear = 1 if(href_list["open"]) @@ -142,7 +142,7 @@ FLOOR SAFES updateUsrDialog() -/obj/structure/safe/attackby(obj/item/I as obj, mob/user as mob) +/obj/structure/safe/attackby(obj/item/I as obj, mob/user as mob, params) if(open) if(I.w_class + space <= maxspace) space += I.w_class @@ -155,7 +155,7 @@ FLOOR SAFES user << "[I] won't fit in [src]." return else - if(istype(I, /obj/item/clothing/tie/stethoscope)) + if(istype(I, /obj/item/clothing/accessory/stethoscope)) user << "Hold [I] in one of your hands while you manipulate the dial." return diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm index f1322e17ad3..914f8847ec0 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm @@ -1,4 +1,5 @@ //Alium nests. Essentially beds with an unbuckle delay that only aliums can buckle mobs to. +#define NEST_RESIST_TIME 1200 /obj/structure/stool/bed/nest name = "alien nest" @@ -18,12 +19,15 @@ buckled_mob.pixel_y = 0 unbuckle() else + if(world.time <= buckled_mob.last_special+NEST_RESIST_TIME) + return buckled_mob.visible_message(\ "[buckled_mob.name] struggles to break free of the gelatinous resin...",\ "You struggle to break free from the gelatinous resin...",\ "You hear squelching...") - spawn(600) + spawn(NEST_RESIST_TIME) if(user && buckled_mob && user.buckled == src) + buckled_mob.last_special = world.time buckled_mob.pixel_y = 0 unbuckle() src.add_fingerprint(user) @@ -66,12 +70,11 @@ overlays.Cut() ..() -/obj/structure/stool/bed/nest/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/stool/bed/nest/attackby(obj/item/weapon/W as obj, mob/user as mob, params) var/aforce = W.force health = max(0, health - aforce) playsound(loc, 'sound/effects/attackblob.ogg', 100, 1) - for(var/mob/M in viewers(src, 7)) - M.show_message("[user] hits [src] with [W]!", 1) + visible_message("[user] hits [src] with [W]!", 1) healthcheck() /obj/structure/stool/bed/nest/proc/healthcheck() diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm index 182d1c64050..2a493bdff37 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm @@ -121,7 +121,7 @@ icon_state = "down" anchored = 0 -/obj/structure/stool/bed/roller/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/stool/bed/roller/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/roller_holder)) if(buckled_mob) manual_unbuckle() @@ -145,7 +145,7 @@ R.add_fingerprint(user) del(src) -/obj/item/roller/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/roller/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/roller_holder)) var/obj/item/roller_holder/RH = W diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm index f892ce74239..6a5598a37ef 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm @@ -16,7 +16,7 @@ handle_rotation() return -/obj/structure/stool/bed/chair/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/stool/bed/chair/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if(istype(W, /obj/item/assembly/shock_kit)) var/obj/item/assembly/shock_kit/SK = W @@ -86,7 +86,7 @@ name = "wooden chair" desc = "Old is never too old to not be in fashion." -/obj/structure/stool/bed/chair/wood/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/stool/bed/chair/wood/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/wrench)) playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) new /obj/item/stack/sheet/wood(src.loc) diff --git a/code/game/objects/structures/stool_bed_chair_nest/stools.dm b/code/game/objects/structures/stool_bed_chair_nest/stools.dm index 78320f38581..050dbb56629 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/stools.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/stools.dm @@ -4,7 +4,6 @@ icon = 'icons/obj/objects.dmi' icon_state = "stool" anchored = 1.0 - flags = FPRINT pressure_resistance = 15 /obj/structure/stool/ex_act(severity) @@ -27,7 +26,7 @@ new /obj/item/stack/sheet/metal(src.loc) del(src) -/obj/structure/stool/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/stool/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/wrench)) playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) new /obj/item/stack/sheet/metal(src.loc) @@ -57,14 +56,14 @@ /obj/item/weapon/stool/attack_self(mob/user as mob) ..() origin.loc = get_turf(src) - user.u_equip(src) + user.unEquip(src) user.visible_message("\blue [user] puts [src] down.", "\blue You put [src] down.") del src /obj/item/weapon/stool/attack(mob/M as mob, mob/user as mob) if (prob(5) && istype(M,/mob/living)) user.visible_message("\red [user] breaks [src] over [M]'s back!.") - user.u_equip(src) + user.unEquip(src) var/obj/item/stack/sheet/metal/m = new/obj/item/stack/sheet/metal m.loc = get_turf(src) del src diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index cd76aef88bb..61dbe8e5e5c 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -24,7 +24,6 @@ var/parts = /obj/item/weapon/table_parts var/flipped = 0 var/health = 100 - var/list/table_contents = list() var/busy = 0 /obj/structure/table/proc/update_adjacent() @@ -41,8 +40,6 @@ update_icon() update_adjacent() - craft_holder = new /datum/crafting_holder(src, "table") - /obj/structure/table/Destroy() update_adjacent() ..() @@ -52,11 +49,6 @@ density = 0 qdel(src) -/obj/structure/table/MouseDrop(atom/over) - if(usr.stat || usr.lying || !Adjacent(usr) || (over != usr)) - return - craft_holder.interact(usr) - /obj/structure/table/update_icon() if(flipped) var/type = 0 @@ -286,26 +278,30 @@ if(prob(75)) destroy() -/obj/structure/table/attack_paw(mob/user) - if(M_HULK in user.mutations) +/obj/structure/table/attack_paw(mob/living/user) + if(HULK in user.mutations) + user.do_attack_animation(src) user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) visible_message("[user] smashes the [src] apart!") destroy() -/obj/structure/table/attack_alien(mob/user) +/obj/structure/table/attack_alien(mob/living/user) + user.do_attack_animation(src) visible_message("[user] slices [src] apart!") destroy() /obj/structure/table/attack_animal(mob/living/simple_animal/user) if(user.environment_smash) + user.do_attack_animation(src) visible_message("[user] smashes [src] apart!") destroy() -/obj/structure/table/attack_hand(mob/user) - if(M_HULK in user.mutations) +/obj/structure/table/attack_hand(mob/living/user) + if(HULK in user.mutations) + user.do_attack_animation(src) visible_message("[user] smashes [src] apart!") user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) destroy() @@ -373,13 +369,14 @@ return if(isrobot(user)) return - user.drop_item() + if(!user.drop_item()) + return if (O.loc != src.loc) step(O, get_dir(O, src)) return -/obj/structure/table/attackby(obj/item/W as obj, mob/user as mob) +/obj/structure/table/attackby(obj/item/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2) var/obj/item/weapon/grab/G = W if (istype(G.affecting, /mob/living)) @@ -420,7 +417,17 @@ O.show_message("\blue The [src] was sliced apart by [user]!", 1, "\red You hear [src] coming apart.", 2) destroy() - user.drop_item(src) + if(!(W.flags & ABSTRACT)) + if(user.drop_item()) + W.Move(loc) + var/list/click_params = params2list(params) + //Center the icon where the user clicked. + if(!click_params || !click_params["icon-x"] || !click_params["icon-y"]) + return + //Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf) + W.pixel_x = Clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) + W.pixel_y = Clamp(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) + return /obj/structure/table/proc/straight_table_check(var/direction) @@ -536,7 +543,7 @@ health = 50 autoignition_temperature = AUTOIGNITION_WOOD // TODO: Special ash subtype that looks like charred table legs. -/obj/structure/table/woodentable/attackby(obj/item/I as obj, mob/user as mob) +/obj/structure/table/woodentable/attackby(obj/item/I as obj, mob/user as mob, params) if (istype(I, /obj/item/stack/tile/grass)) del(I) @@ -583,8 +590,17 @@ del(src) return - user.drop_item(src) - //if(W && W.loc) W.loc = src.loc + if(!(I.flags & ABSTRACT)) + if(user.drop_item()) + I.Move(loc) + var/list/click_params = params2list(params) + //Center the icon where the user clicked. + if(!click_params || !click_params["icon-x"] || !click_params["icon-y"]) + return + //Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf) + I.pixel_x = Clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) + I.pixel_y = Clamp(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) + return 1 /obj/structure/table/woodentable/poker //No specialties, Just a mapping object. @@ -593,7 +609,7 @@ icon_state = "pokertable" -/obj/structure/table/woodentable/poker/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/table/woodentable/poker/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/grab)) var/obj/item/weapon/grab/G = W @@ -635,7 +651,17 @@ del(src) return - user.drop_item(src) + if(!(W.flags & ABSTRACT)) + if(user.drop_item()) + W.Move(loc) + var/list/click_params = params2list(params) + //Center the icon where the user clicked. + if(!click_params || !click_params["icon-x"] || !click_params["icon-y"]) + return + //Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf) + W.pixel_x = Clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) + W.pixel_y = Clamp(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) + return 1 @@ -656,7 +682,7 @@ else return ..() -/obj/structure/table/reinforced/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/table/reinforced/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/WT = W if(WT.remove_fuel(0, user)) @@ -692,7 +718,6 @@ icon = 'icons/obj/objects.dmi' icon_state = "rack" density = 1 - flags = FPRINT anchored = 1.0 throwpass = 1 //You can throw objects over this, despite it's density. var/parts = /obj/item/weapon/rack_parts @@ -738,12 +763,13 @@ return if(isrobot(user)) return - user.drop_item() + if(!user.drop_item()) + return if (O.loc != src.loc) step(O, get_dir(O, src)) return -/obj/structure/rack/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/rack/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/wrench)) new /obj/item/weapon/rack_parts( src.loc ) playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) @@ -751,8 +777,9 @@ return if(isrobot(user)) return - user.drop_item() - if(W && W.loc) W.loc = src.loc + if(!(W.flags & ABSTRACT)) + if(user.drop_item()) + W.Move(loc) return /obj/structure/rack/meteorhit(obj/O as obj) @@ -760,26 +787,29 @@ /obj/structure/table/attack_hand(mob/user) - if(M_HULK in user.mutations) + if(HULK in user.mutations) visible_message("[user] smashes [src] apart!") user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) destroy() -/obj/structure/rack/attack_paw(mob/user) - if(M_HULK in user.mutations) +/obj/structure/rack/attack_paw(mob/living/user) + if(HULK in user.mutations) + user.do_attack_animation(src) user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) visible_message("[user] smashes [src] apart!") destroy() -/obj/structure/rack/attack_alien(mob/user) +/obj/structure/rack/attack_alien(mob/living/user) + user.do_attack_animation(src) visible_message("[user] slices [src] apart!") destroy() /obj/structure/rack/attack_animal(mob/living/simple_animal/user) if(user.environment_smash) + user.do_attack_animation(src) visible_message("[user] smashes [src] apart!") destroy() diff --git a/code/game/objects/structures/tables_racks.dm.bak b/code/game/objects/structures/tables_racks.dm.bak deleted file mode 100644 index be396a3196f..00000000000 --- a/code/game/objects/structures/tables_racks.dm.bak +++ /dev/null @@ -1,480 +0,0 @@ -/* Tables and Racks - * Contains: - * Tables - * Wooden tables - * Reinforced tables - * Racks - */ - - -/* - * Tables - */ -/obj/structure/table - name = "table" - desc = "A square piece of metal standing on four metal legs. It can not move." - icon = 'icons/obj/structures.dmi' - icon_state = "table" - density = 1 - anchored = 1.0 - layer = 2.8 - throwpass = 1 //You can throw objects over this, despite it's density.") - var/parts = /obj/item/weapon/table_parts - -/obj/structure/table/New() - ..() - for(var/obj/structure/table/T in src.loc) - if(T != src) - del(T) - update_icon() - for(var/direction in list(1,2,4,8,5,6,9,10)) - if(locate(/obj/structure/table,get_step(src,direction))) - var/obj/structure/table/T = locate(/obj/structure/table,get_step(src,direction)) - T.update_icon() - -/obj/structure/table/Del() - for(var/direction in list(1,2,4,8,5,6,9,10)) - if(locate(/obj/structure/table,get_step(src,direction))) - var/obj/structure/table/T = locate(/obj/structure/table,get_step(src,direction)) - T.update_icon() - ..() - -/obj/structure/table/proc/destroy() - new parts(loc) - density = 0 - del(src) - - -/obj/structure/table/update_icon() - spawn(2) //So it properly updates when deleting - var/dir_sum = 0 - for(var/direction in list(1,2,4,8,5,6,9,10)) - var/skip_sum = 0 - for(var/obj/structure/window/W in src.loc) - if(W.dir == direction) //So smooth tables don't go smooth through windows - skip_sum = 1 - continue - var/inv_direction //inverse direction - switch(direction) - if(1) - inv_direction = 2 - if(2) - inv_direction = 1 - if(4) - inv_direction = 8 - if(8) - inv_direction = 4 - if(5) - inv_direction = 10 - if(6) - inv_direction = 9 - if(9) - inv_direction = 6 - if(10) - inv_direction = 5 - for(var/obj/structure/window/W in get_step(src,direction)) - if(W.dir == inv_direction) //So smooth tables don't go smooth through windows when the window is on the other table's tile - skip_sum = 1 - continue - if(!skip_sum) //means there is a window between the two tiles in this direction - if(locate(/obj/structure/table,get_step(src,direction))) - if(direction <5) - dir_sum += direction - else - if(direction == 5) //This permits the use of all table directions. (Set up so clockwise around the central table is a higher value, from north) - dir_sum += 16 - if(direction == 6) - dir_sum += 32 - if(direction == 8) //Aherp and Aderp. Jezes I am stupid. -- SkyMarshal - dir_sum += 8 - if(direction == 10) - dir_sum += 64 - if(direction == 9) - dir_sum += 128 - - var/table_type = 0 //stand_alone table - if(dir_sum%16 in cardinal) - table_type = 1 //endtable - dir_sum %= 16 - if(dir_sum%16 in list(3,12)) - table_type = 2 //1 tile thick, streight table - if(dir_sum%16 == 3) //3 doesn't exist as a dir - dir_sum = 2 - if(dir_sum%16 == 12) //12 doesn't exist as a dir. - dir_sum = 4 - if(dir_sum%16 in list(5,6,9,10)) - if(locate(/obj/structure/table,get_step(src.loc,dir_sum%16))) - table_type = 3 //full table (not the 1 tile thick one, but one of the 'tabledir' tables) - else - table_type = 2 //1 tile thick, corner table (treated the same as streight tables in code later on) - dir_sum %= 16 - if(dir_sum%16 in list(13,14,7,11)) //Three-way intersection - table_type = 5 //full table as three-way intersections are not sprited, would require 64 sprites to handle all combinations. TOO BAD -- SkyMarshal - switch(dir_sum%16) //Begin computation of the special type tables. --SkyMarshal - if(7) - if(dir_sum == 23) - table_type = 6 - dir_sum = 8 - else if(dir_sum == 39) - dir_sum = 4 - table_type = 6 - else if(dir_sum == 55 || dir_sum == 119 || dir_sum == 247 || dir_sum == 183) - dir_sum = 4 - table_type = 3 - else - dir_sum = 4 - if(11) - if(dir_sum == 75) - dir_sum = 5 - table_type = 6 - else if(dir_sum == 139) - dir_sum = 9 - table_type = 6 - else if(dir_sum == 203 || dir_sum == 219 || dir_sum == 251 || dir_sum == 235) - dir_sum = 8 - table_type = 3 - else - dir_sum = 8 - if(13) - if(dir_sum == 29) - dir_sum = 10 - table_type = 6 - else if(dir_sum == 141) - dir_sum = 6 - table_type = 6 - else if(dir_sum == 189 || dir_sum == 221 || dir_sum == 253 || dir_sum == 157) - dir_sum = 1 - table_type = 3 - else - dir_sum = 1 - if(14) - if(dir_sum == 46) - dir_sum = 1 - table_type = 6 - else if(dir_sum == 78) - dir_sum = 2 - table_type = 6 - else if(dir_sum == 110 || dir_sum == 254 || dir_sum == 238 || dir_sum == 126) - dir_sum = 2 - table_type = 3 - else - dir_sum = 2 //These translate the dir_sum to the correct dirs from the 'tabledir' icon_state. - if(dir_sum%16 == 15) - table_type = 4 //4-way intersection, the 'middle' table sprites will be used. - - if(istype(src,/obj/structure/table/reinforced)) - switch(table_type) - if(0) - icon_state = "reinf_table" - if(1) - icon_state = "reinf_1tileendtable" - if(2) - icon_state = "reinf_1tilethick" - if(3) - icon_state = "reinf_tabledir" - if(4) - icon_state = "reinf_middle" - if(5) - icon_state = "reinf_tabledir2" - if(6) - icon_state = "reinf_tabledir3" - else if(istype(src,/obj/structure/table/woodentable)) - switch(table_type) - if(0) - icon_state = "wood_table" - if(1) - icon_state = "wood_1tileendtable" - if(2) - icon_state = "wood_1tilethick" - if(3) - icon_state = "wood_tabledir" - if(4) - icon_state = "wood_middle" - if(5) - icon_state = "wood_tabledir2" - if(6) - icon_state = "wood_tabledir3" - else - switch(table_type) - if(0) - icon_state = "table" - if(1) - icon_state = "table_1tileendtable" - if(2) - icon_state = "table_1tilethick" - if(3) - icon_state = "tabledir" - if(4) - icon_state = "table_middle" - if(5) - icon_state = "tabledir2" - if(6) - icon_state = "tabledir3" - if (dir_sum in list(1,2,4,8,5,6,9,10)) - dir = dir_sum - else - dir = 2 - -/obj/structure/table/ex_act(severity) - switch(severity) - if(1.0) - del(src) - return - if(2.0) - if (prob(50)) - del(src) - return - if(3.0) - if (prob(25)) - destroy() - else - return - - -/obj/structure/table/blob_act() - if(prob(75)) - destroy() - -/obj/structure/table/attack_paw(mob/user) - if(HULK in user.mutations) - user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) - visible_message("[user] smashes the [src] apart!") - destroy() - - -/obj/structure/table/attack_alien(mob/user) - visible_message("[user] slices [src] apart!") - -/obj/structure/table/attack_animal(mob/living/simple_animal/user) - if(user.wall_smash) - visible_message("[user] smashes [src] apart!") - destroy() - - - -/obj/structure/table/attack_hand(mob/user) - if(HULK in user.mutations) - visible_message("[user] smashes [src] apart!") - user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) - destroy() - -/obj/structure/table/attack_tk() // no telehulk sorry - return - -/obj/structure/table/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 - - if(istype(mover) && mover.checkpass(PASSTABLE)) - return 1 - else - return 0 - - -/obj/structure/table/MouseDrop_T(obj/O as obj, mob/user as mob) - - if ((!( istype(O, /obj/item/weapon) ) || user.get_active_hand() != O)) - return - if(isrobot(user)) - return - user.drop_item() - if (O.loc != src.loc) - step(O, get_dir(O, src)) - return - - -/obj/structure/table/attackby(obj/item/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2) - var/obj/item/weapon/grab/G = W - if (istype(G.affecting, /mob/living)) - var/mob/living/M = G.affecting - if (G.state < 2) - if(user.a_intent == "hurt") - if (prob(15)) M.Weaken(5) - M.apply_damage(8,def_zone = "head") - visible_message("\red [G.assailant] slams [G.affecting]'s face against \the [src]!") - playsound(src.loc, 'sound/weapons/tablehit1.ogg', 50, 1) - else - user << "\red You need a better grip to do that!" - return - else - G.affecting.loc = src.loc - G.affecting.Weaken(5) - visible_message("\red [G.assailant] puts [G.affecting] on \the [src].") - del(W) - return - - if (istype(W, /obj/item/weapon/wrench)) - user << "\blue Now disassembling table" - playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) - if(do_after(user,50)) - destroy() - return - - if(isrobot(user)) - return - - if(istype(W, /obj/item/weapon/melee/energy/blade)) - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, src.loc) - spark_system.start() - playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1) - playsound(src.loc, "sparks", 50, 1) - for(var/mob/O in viewers(user, 4)) - O.show_message("\blue The [src] was sliced apart by [user]!", 1, "\red You hear [src] coming apart.", 2) - destroy() - - user.drop_item(src) - return - - -/* - * Wooden tables - */ -/obj/structure/table/woodentable - name = "wooden table" - desc = "Do not apply fire to this. Rumour says it burns easily." - icon_state = "wood_table" - parts = /obj/item/weapon/table_parts/wood - -/* - * Reinforced tables - */ -/obj/structure/table/reinforced - name = "reinforced table" - desc = "A version of the four legged table. It is stronger." - icon_state = "reinf_table" - var/status = 2 - parts = /obj/item/weapon/table_parts/reinforced - - -/obj/structure/table/reinforced/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/weldingtool)) - var/obj/item/weapon/weldingtool/WT = W - if(WT.remove_fuel(0, user)) - if(src.status == 2) - user << "\blue Now weakening the reinforced table" - playsound(src.loc, 'sound/items/Welder.ogg', 50, 1) - if (do_after(user, 50)) - if(!src || !WT.isOn()) return - user << "\blue Table weakened" - src.status = 1 - else - user << "\blue Now strengthening the reinforced table" - playsound(src.loc, 'sound/items/Welder.ogg', 50, 1) - if (do_after(user, 50)) - if(!src || !WT.isOn()) return - user << "\blue Table strengthened" - src.status = 2 - return - return - - if (istype(W, /obj/item/weapon/wrench)) - if(src.status == 2) - return - - ..() - -/* - * Racks - */ -/obj/structure/rack - name = "rack" - desc = "Different from the Middle Ages version." - icon = 'icons/obj/objects.dmi' - icon_state = "rack" - density = 1 - flags = FPRINT - anchored = 1.0 - throwpass = 1 //You can throw objects over this, despite it's density. - -/obj/structure/rack/ex_act(severity) - switch(severity) - if(1.0) - del(src) - if(2.0) - del(src) - if(prob(50)) - new /obj/item/weapon/rack_parts(src.loc) - if(3.0) - if(prob(25)) - del(src) - new /obj/item/weapon/rack_parts(src.loc) - -/obj/structure/rack/blob_act() - if(prob(75)) - del(src) - return - else if(prob(50)) - new /obj/item/weapon/rack_parts(src.loc) - del(src) - return - -/obj/structure/rack/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 - if(src.density == 0) //Because broken racks -Agouri |TODO: SPRITE!| - return 1 - if(istype(mover) && mover.checkpass(PASSTABLE)) - return 1 - else - return 0 - -/obj/structure/rack/MouseDrop_T(obj/O as obj, mob/user as mob) - if ((!( istype(O, /obj/item/weapon) ) || user.get_active_hand() != O)) - return - if(isrobot(user)) - return - user.drop_item() - if (O.loc != src.loc) - step(O, get_dir(O, src)) - return - -/obj/structure/rack/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/wrench)) - new /obj/item/weapon/rack_parts( src.loc ) - playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) - del(src) - return - if(isrobot(user)) - return - user.drop_item() - if(W && W.loc) W.loc = src.loc - return - -/obj/structure/rack/meteorhit(obj/O as obj) - del(src) - - -/obj/structure/table/attack_hand(mob/user) - if(HULK in user.mutations) - visible_message("[user] smashes [src] apart!") - user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) - new /obj/item/weapon/rack_parts(loc) - density = 0 - del(src) - - -/obj/structure/rack/attack_paw(mob/user) - if(HULK in user.mutations) - user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) - visible_message("[user] smashes [src] apart!") - new /obj/item/weapon/rack_parts(loc) - density = 0 - del(src) - - -/obj/structure/rack/attack_alien(mob/user) - visible_message("[user] slices [src] apart!") - new /obj/item/weapon/rack_parts(loc) - density = 0 - del(src) - - -/obj/structure/rack/attack_animal(mob/living/simple_animal/user) - if(user.wall_smash) - visible_message("[user] smashes [src] apart!") - new /obj/item/weapon/rack_parts(loc) - density = 0 - del(src) - -/obj/structure/rack/attack_tk() // no telehulk sorry - return diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm index 37e019963fc..3d8b13ff08b 100644 --- a/code/game/objects/structures/tank_dispenser.dm +++ b/code/game/objects/structures/tank_dispenser.dm @@ -42,7 +42,7 @@ return -/obj/structure/dispenser/attackby(obj/item/I as obj, mob/user as mob) +/obj/structure/dispenser/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/weapon/tank/oxygen) || istype(I, /obj/item/weapon/tank/air) || istype(I, /obj/item/weapon/tank/anesthetic)) if(oxygentanks < 10) user.drop_item() diff --git a/code/game/objects/structures/target_stake.dm b/code/game/objects/structures/target_stake.dm index 1e9ac37a558..08bcc985611 100644 --- a/code/game/objects/structures/target_stake.dm +++ b/code/game/objects/structures/target_stake.dm @@ -18,7 +18,7 @@ pinned_target = null density = 1 - attackby(obj/item/W as obj, mob/user as mob) + attackby(obj/item/W as obj, mob/user as mob, params) // Putting objects on the stake. Most importantly, targets if(pinned_target) return // get rid of that pinned target first! diff --git a/code/game/objects/structures/transit_tubes/station.dm b/code/game/objects/structures/transit_tubes/station.dm index c1026c4e207..4806844ac4d 100644 --- a/code/game/objects/structures/transit_tubes/station.dm +++ b/code/game/objects/structures/transit_tubes/station.dm @@ -67,7 +67,7 @@ break -/obj/structure/transit_tube/station/attackby(obj/item/W, mob/user) +/obj/structure/transit_tube/station/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/weapon/grab) && icon_state == "open") var/obj/item/weapon/grab/G = W if(ismob(G.affecting) && G.state >= GRAB_AGGRESSIVE) diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index c3032dbe840..74e351702ac 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -42,7 +42,7 @@ /obj/structure/toilet/update_icon() icon_state = "toilet[open][cistern]" -/obj/structure/toilet/attackby(obj/item/I as obj, mob/living/user as mob) +/obj/structure/toilet/attackby(obj/item/I as obj, mob/living/user as mob, params) if(istype(I, /obj/item/weapon/crowbar)) user << "You start to [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"]." playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 50, 1) @@ -99,7 +99,7 @@ density = 0 anchored = 1 -/obj/structure/urinal/attackby(obj/item/I as obj, mob/user as mob) +/obj/structure/urinal/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/weapon/grab)) var/obj/item/weapon/grab/G = I if(isliving(G.affecting)) @@ -149,7 +149,7 @@ for (var/atom/movable/G in src.loc) G.clean_blood() -/obj/machinery/shower/attackby(obj/item/I as obj, mob/user as mob) +/obj/machinery/shower/attackby(obj/item/I as obj, mob/user as mob, params) if(I.type == /obj/item/device/analyzer) user << "The water temperature seems to be [watertemp]." if(istype(I, /obj/item/weapon/wrench)) @@ -360,7 +360,7 @@ V.show_message("\blue [user] washes their hands using \the [src].") -/obj/structure/sink/attackby(obj/item/O as obj, mob/user as mob) +/obj/structure/sink/attackby(obj/item/O as obj, mob/user as mob, params) if(busy) user << "\red Someone's already washing here." return @@ -424,7 +424,7 @@ ..() icon_state = "puddle" -/obj/structure/sink/puddle/attackby(obj/item/O as obj, mob/user as mob) +/obj/structure/sink/puddle/attackby(obj/item/O as obj, mob/user as mob, params) icon_state = "puddle-splash" ..() icon_state = "puddle" diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm index b9e5b2a34f6..b41b5be8afc 100644 --- a/code/game/objects/structures/windoor_assembly.dm +++ b/code/game/objects/structures/windoor_assembly.dm @@ -27,13 +27,6 @@ obj/structure/windoor_assembly var/secure = 0 //Whether or not this creates a secure windoor var/state = "01" //How far the door assembly has progressed -/obj/structure/windoor_assembly/proc/update_nearby_tiles(need_rebuild) - if(!air_master) return 0 - - air_master.mark_for_update(loc) - - return 1 - obj/structure/windoor_assembly/New(dir=NORTH) ..() src.ini_dir = src.dir @@ -64,7 +57,7 @@ obj/structure/windoor_assembly/Destroy() return 1 -/obj/structure/windoor_assembly/attackby(obj/item/W as obj, mob/user as mob) +/obj/structure/windoor_assembly/attackby(obj/item/W as obj, mob/user as mob, params) //I really should have spread this out across more states but thin little windoors are hard to sprite. add_fingerprint(user) switch(state) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index d6f9288d05f..3882da9cef3 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -65,7 +65,7 @@ var/global/wcColored if(health <= 0) var/pdiff=performWallPressureCheck(src.loc) if(pdiff>0) - message_admins("Window destroyed by [Proj.firer.name] ([formatPlayerPanel(Proj.firer,Proj.firer.ckey)]) via \an [Proj]! pdiff = [pdiff] at [formatJumpTo(loc)]!") + msg_admin_attack("Window destroyed by [Proj.firer.name] ([formatPlayerPanel(Proj.firer,Proj.firer.ckey)]) via \an [Proj]! pdiff = [pdiff] at [formatJumpTo(loc)]!") log_admin("Window destroyed by ([Proj.firer.ckey]) via \an [Proj]! pdiff = [pdiff] at [loc]!") destroy() return @@ -135,38 +135,40 @@ var/global/wcColored var/pdiff=performWallPressureCheck(src.loc) if(pdiff>0) if(M) - message_admins("Window with pdiff [pdiff] at [formatJumpTo(loc)] deanchored by [M.real_name] ([formatPlayerPanel(M,M.ckey)])!") + msg_admin_attack("Window with pdiff [pdiff] at [formatJumpTo(loc)] deanchored by [M.real_name] ([formatPlayerPanel(M,M.ckey)])!") log_admin("Window with pdiff [pdiff] at [loc] deanchored by [M.real_name] ([M.ckey])!") else - message_admins("Window with pdiff [pdiff] at [formatJumpTo(loc)] deanchored by [AM]!") + msg_admin_attack("Window with pdiff [pdiff] at [formatJumpTo(loc)] deanchored by [AM]!") log_admin("Window with pdiff [pdiff] at [loc] deanchored by [AM]!") if(health <= 0) var/pdiff=performWallPressureCheck(src.loc) if(pdiff>0) if(M) - message_admins("Window with pdiff [pdiff] at [formatJumpTo(loc)] destroyed by [M.real_name] ([formatPlayerPanel(M,M.ckey)])!") + msg_admin_attack("Window with pdiff [pdiff] at [formatJumpTo(loc)] destroyed by [M.real_name] ([formatPlayerPanel(M,M.ckey)])!") log_admin("Window with pdiff [pdiff] at [loc] destroyed by [M.real_name] ([M.ckey])!") else - message_admins("Window with pdiff [pdiff] at [formatJumpTo(loc)] destroyed by [AM]!") + msg_admin_attack("Window with pdiff [pdiff] at [formatJumpTo(loc)] destroyed by [AM]!") log_admin("Window with pdiff [pdiff] at [loc] destroyed by [AM]!") destroy() /obj/structure/window/attack_hand(mob/user as mob) - if(M_HULK in user.mutations) + if(HULK in user.mutations) user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!")) user.visible_message("[user] smashes through [src]!") var/pdiff=performWallPressureCheck(src.loc) if(pdiff>0) - message_admins("Window destroyed by hulk [user.real_name] ([formatPlayerPanel(user,user.ckey)]) with pdiff [pdiff] at [formatJumpTo(loc)]!") + msg_admin_attack("Window destroyed by hulk [user.real_name] ([formatPlayerPanel(user,user.ckey)]) with pdiff [pdiff] at [formatJumpTo(loc)]!") log_admin("Window destroyed by hulk [user.real_name] ([user.ckey]) with pdiff [pdiff] at [loc]!") destroy() else if (usr.a_intent == "harm") + user.changeNext_move(CLICK_CD_MELEE) playsound(get_turf(src), 'sound/effects/glassknock.ogg', 80, 1) usr.visible_message("\red [usr.name] bangs against the [src.name]!", \ "\red You bang against the [src.name]!", \ "You hear a banging sound.") else + user.changeNext_move(CLICK_CD_MELEE) playsound(src.loc, 'sound/effects/glassknock.ogg', 80, 1) usr.visible_message("[usr.name] knocks on the [src.name].", \ "You knock on the [src.name].", \ @@ -177,38 +179,40 @@ var/global/wcColored /obj/structure/window/attack_paw(mob/user as mob) return attack_hand(user) -/obj/structure/window/proc/attack_generic(mob/user as mob, damage = 0) //used by attack_alien, attack_animal, and attack_slime +/obj/structure/window/proc/attack_generic(mob/living/user as mob, damage = 0) //used by attack_alien, attack_animal, and attack_slime + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) health -= damage if(health <= 0) user.visible_message("[user] smashes through [src]!") var/pdiff=performWallPressureCheck(src.loc) if(pdiff>0) - message_admins("Window destroyed by [user.real_name] ([formatPlayerPanel(user,user.ckey)]) with pdiff [pdiff] at [formatJumpTo(loc)]!") + msg_admin_attack("Window destroyed by [user.real_name] ([formatPlayerPanel(user,user.ckey)]) with pdiff [pdiff] at [formatJumpTo(loc)]!") destroy() else //for nicer text~ user.visible_message("[user] smashes into [src]!") playsound(loc, 'sound/effects/Glasshit.ogg', 100, 1) -/obj/structure/window/attack_alien(mob/user as mob) +/obj/structure/window/attack_alien(mob/living/user as mob) if(islarva(user)) return attack_generic(user, 15) -/obj/structure/window/attack_animal(mob/user as mob) +/obj/structure/window/attack_animal(mob/living/user as mob) if(!isanimal(user)) return var/mob/living/simple_animal/M = user if(M.melee_damage_upper <= 0) return attack_generic(M, M.melee_damage_upper) -/obj/structure/window/attack_slime(mob/user as mob) +/obj/structure/window/attack_slime(mob/living/user as mob) var/mob/living/carbon/slime/S = user if (!S.is_adult) return attack_generic(user, rand(10, 15)) -/obj/structure/window/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/window/attackby(obj/item/weapon/W as obj, mob/living/user as mob, params) if(!istype(W)) return//I really wish I did not need this if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2) var/obj/item/weapon/grab/G = W @@ -240,7 +244,7 @@ var/global/wcColored return if(W.flags & NOBLUDGEON) return - + if(istype(W, /obj/item/weapon/screwdriver)) if(reinf && state >= 1) state = 3 - state @@ -254,7 +258,7 @@ var/global/wcColored if(!anchored) var/pdiff=performWallPressureCheck(src.loc) if(pdiff>0) - message_admins("Window with pdiff [pdiff] deanchored by [user.real_name] ([formatPlayerPanel(user,user.ckey)]) at [formatJumpTo(loc)]!") + msg_admin_attack("Window with pdiff [pdiff] deanchored by [user.real_name] ([formatPlayerPanel(user,user.ckey)]) at [formatJumpTo(loc)]!") log_admin("Window with pdiff [pdiff] deanchored by [user.real_name] ([user.ckey]) at [loc]!") else if(!reinf) anchored = !anchored @@ -264,7 +268,7 @@ var/global/wcColored if(!anchored) var/pdiff=performWallPressureCheck(src.loc) if(pdiff>0) - message_admins("Window with pdiff [pdiff] deanchored by [user.real_name] ([formatPlayerPanel(user,user.ckey)]) at [formatJumpTo(loc)]!") + msg_admin_attack("Window with pdiff [pdiff] deanchored by [user.real_name] ([formatPlayerPanel(user,user.ckey)]) at [formatJumpTo(loc)]!") log_admin("Window with pdiff [pdiff] deanchored by [user.real_name] ([user.ckey]) at [loc]!") else if(istype(W, /obj/item/weapon/crowbar) && reinf && state <= 1) state = 1 - state @@ -279,7 +283,7 @@ var/global/wcColored continue if(G.amount>=G.max_amount) continue - G.attackby(NG, user) + G.attackby(NG, user, params) if (reinf) var/obj/item/stack/rods/NR = new (src.loc) @@ -288,7 +292,7 @@ var/global/wcColored continue if(R.amount>=R.max_amount) continue - R.attackby(NR, user) + R.attackby(NR, user, params) user << "You have disassembled the window." disassembled = 1 @@ -298,6 +302,7 @@ var/global/wcColored del(src) else if(W.damtype == BRUTE || W.damtype == BURN) + user.changeNext_move(CLICK_CD_MELEE) hit(W.force) if(health <= 7) anchored = 0 @@ -305,7 +310,7 @@ var/global/wcColored step(src, get_dir(user, src)) var/pdiff=performWallPressureCheck(src.loc) if(pdiff>0) - message_admins("Window with pdiff [pdiff] deanchored by [user.real_name] ([formatPlayerPanel(user,user.ckey)]) at [formatJumpTo(loc)]!") + msg_admin_attack("Window with pdiff [pdiff] deanchored by [user.real_name] ([formatPlayerPanel(user,user.ckey)]) at [formatJumpTo(loc)]!") log_admin("Window with pdiff [pdiff] deanchored by [user.real_name] ([user.ckey]) at [loc]!") else playsound(loc, 'sound/effects/Glasshit.ogg', 75, 1) @@ -325,7 +330,7 @@ var/global/wcColored if(health <= 0) var/pdiff=performWallPressureCheck(src.loc) if(pdiff>0) - message_admins("Window with pdiff [pdiff] broken at [formatJumpTo(loc)]!") + msg_admin_attack("Window with pdiff [pdiff] broken at [formatJumpTo(loc)]!") destroy() return @@ -403,14 +408,6 @@ var/global/wcColored dir = ini_dir update_nearby_tiles(need_rebuild=1) - -//This proc has to do with airgroups and atmos, it has nothing to do with smoothwindows, that's update_nearby_tiles(). -/obj/structure/window/proc/update_nearby_tiles(need_rebuild) - if(!air_master) return 0 - air_master.mark_for_update(get_turf(src)) - - return 1 - //checks if this window is full-tile one /obj/structure/window/proc/is_fulltile() if(dir & (dir - 1)) diff --git a/code/game/response_team.dm b/code/game/response_team.dm index 3b82543e80a..e26f40bfae4 100644 --- a/code/game/response_team.dm +++ b/code/game/response_team.dm @@ -48,30 +48,42 @@ var/can_call_ert if(!send_emergency_team) usr << "No emergency response team is currently being sent." return + /* if(admin_emergency_team) usr << "An emergency response team has already been sent." return */ - if(jobban_isbanned(usr, "Syndicate") || jobban_isbanned(usr, "Emergency Response Team") || jobban_isbanned(usr, "Security Officer")) - usr << "You are jobbanned from the emergency reponse team!" + + if(jobban_isbanned(usr, "Emergency Response Team")) + usr << "You are jobbanned from the emergency reponse team!" + return + + var/responseteam_age = 21 // 21 days to play as an ERT member + var/player_age_check = check_client_age(usr.client, responseteam_age) + if(player_age_check && config.use_age_restriction_for_antags) + usr << "This role is not yet available to you. You need to wait another [player_age_check] days." return - if(response_team_members.len > 5) usr << "The emergency response team is already full!" + if(response_team_members.len > 6) usr << "The emergency response team is already full!" - - for (var/obj/effect/landmark/L in landmarks_list) if (L.name == "Commando") + for (var/obj/effect/landmark/L in landmarks_list) if (L.name == "Response Team") L.name = null//Reserving the place. - var/new_name = input(usr, "Pick a name","Name") as null|text + /*var/new_name = alert(usr, "Pick a name","Name") as null|text if(!new_name)//Somebody changed his mind, place is available again. L.name = "Commando" + return*/ + if(alert(usr, "Join the Emergency Response Team?", "Emergency Response Team", "Yes", "No") == "No") + L.name = "Response Team" return + var/leader_selected = isemptylist(response_team_members) if(!src.client) return var/client/C = src.client - var/mob/living/carbon/human/new_commando = C.create_response_team(L.loc, leader_selected, new_name) + var/mob/living/carbon/human/new_commando = C.create_response_team(L.loc, leader_selected) del(L) new_commando.mind.key = usr.key new_commando.key = usr.key + new_commando.update_icons() new_commando << "\blue You are [!leader_selected?"a member":"the LEADER"] of an Emergency Response Team, a type of military division, under CentComm's service. There is a code red alert on [station_name()], you are tasked to go and fix the problem." new_commando << "You should first gear up and discuss a plan with your team. More members may be joining, don't move out before you're ready." @@ -142,11 +154,11 @@ proc/trigger_armed_response_team(var/force = 0) // there's only a certain chance a team will be sent if(!prob(send_team_chance)) - command_alert("It would appear that an emergency response team was requested for [station_name()]. Unfortunately, we were unable to send one at this time.", "Central Command") + command_announcement.Announce("It would appear that an emergency response team was requested for [station_name()]. Unfortunately, we were unable to send one at this time.", "Central Command") can_call_ert = 0 // Only one call per round, ladies. return - command_alert("It would appear that an emergency response team was requested for [station_name()]. We will prepare and send one as soon as possible.", "Central Command") + command_announcement.Announce("It would appear that an emergency response team was requested for [station_name()]. We will prepare and send one as soon as possible.", "Central Command") can_call_ert = 0 // Only one call per round, gentleman. send_emergency_team = 1 @@ -168,7 +180,7 @@ proc/trigger_armed_response_team(var/force = 0) continue */ -/client/proc/create_response_team(obj/spawn_location, leader_selected = 0, commando_name) +/client/proc/create_response_team(obj/spawn_location, leader_selected = 0) //usr << "\red ERT has been temporarily disabled. Talk to a coder." //return @@ -178,7 +190,7 @@ proc/trigger_armed_response_team(var/force = 0) //todo: god damn this. //make it a panel, like in character creation - var/new_facial = input("Please select facial hair color.", "Character Generation") as color + /*var/new_facial = input("Please select facial hair color.", "Character Generation") as color if(new_facial) M.r_facial = hex2num(copytext(new_facial, 2, 4)) M.g_facial = hex2num(copytext(new_facial, 4, 6)) @@ -262,14 +274,20 @@ proc/trigger_armed_response_team(var/force = 0) if(new_gender == "Male") M.gender = MALE else - M.gender = FEMALE + M.gender = FEMALE*/ //M.rebuild_appearance() + + M.gender = pick(MALE, FEMALE) + + var/datum/preferences/A = new()//Randomize appearance for the commando. + A.randomize_appearance_for(M) + M.update_hair() M.update_body() M.check_dna(M) - M.real_name = commando_name - M.name = commando_name + M.real_name = "[!leader_selected ? pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major") : pick("Lieutenant", "Captain", "Major")] [pick(last_names)]" + M.name = M.real_name M.age = !leader_selected ? rand(23,35) : rand(35,45) M.dna.ready_dna(M)//Creates DNA. @@ -283,10 +301,160 @@ proc/trigger_armed_response_team(var/force = 0) if(!(M.mind in ticker.minds)) ticker.minds += M.mind//Adds them to regular mind list. M.loc = spawn_location - M.equip_strike_team(leader_selected) + + if(leader_selected) + equip_emergencyresponsesquad(M, "commander") + else + switch(input("Which class?") in list("Security","Engineer","Medical")) + if("Security") + equip_emergencyresponsesquad(M, "sec") + if("Engineer") + equip_emergencyresponsesquad(M, "eng") + if("Medical") + equip_emergencyresponsesquad(M, "med") return M -/mob/living/carbon/human/proc/equip_strike_team(leader_selected = 0) +/proc/equip_emergencyresponsesquad(var/mob/living/carbon/human/M, var/ertrole) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset/ert/alt(src), slot_l_ear) + M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform) + + var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(M) + L.imp_in = M + L.implanted = 1 + + switch(ertrole) + if("commander") + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots/advance(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves) + M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/ert/commander(M), slot_wear_suit) + M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/captain(M), slot_back) + M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses/sechud(M), slot_glasses) + + var/obj/item/weapon/card/id/W = new(src) + W.assignment = "Emergency Response Team Leader" + W.registered_name = M.real_name + W.name = "[M.real_name]'s ID Card (Emergency Response Team - Commander)" + W.icon_state = "centcom" + W.access = get_all_accesses() + W.access += list(access_cent_general, access_cent_living, access_cent_medical, access_cent_storage, access_cent_thunder, access_cent_teleporter) + M.equip_to_slot_or_del(W, slot_wear_id) + + var/obj/item/device/pda/heads/pda = new(src) + pda.owner = M.real_name + pda.ownjob = "Emergency Response Team Leader" + pda.name = "PDA-[M.real_name] ([pda.ownjob])" + M.equip_to_slot_or_del(pda, slot_wear_pda) + + M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/response_team(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/ert/commander(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/swat(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/pinpointer(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(M), slot_in_backpack) + + M.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/security/response_team(M), slot_belt) + + if("sec") + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves) + M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/ert/security(M), slot_wear_suit) + M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(M), slot_back) + M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses/sechud(M), slot_glasses) + + var/obj/item/weapon/card/id/W = new(src) + W.assignment = "Emergency Response Team" + W.registered_name = M.real_name + W.name = "[M.real_name]'s ID Card (Emergency Response Team - Officer)" + W.icon_state = "centcom" + W.access = get_all_accesses() + W.access += list(access_cent_general, access_cent_living, access_cent_thunder) + M.equip_to_slot_or_del(W, slot_wear_id) + + var/obj/item/device/pda/heads/pda = new(src) + pda.owner = M.real_name + pda.ownjob = "Emergency Response Team" + pda.name = "PDA-[M.real_name] ([pda.ownjob])" + pda.icon_state = "pda-security" + M.equip_to_slot_or_del(pda, slot_wear_pda) + + M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/response_team(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/handcuffs(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/ert/security(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/swat(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun/nuclear(M), slot_in_backpack) + + M.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/security/response_team(M), slot_belt) + + if("med") + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves) + M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/ert/medical(M), slot_wear_suit) + M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/medic(M), slot_back) + M.equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/health_advanced(M), slot_glasses) + + var/obj/item/weapon/card/id/W = new(src) + W.assignment = "Emergency Response Team" + W.registered_name = M.real_name + W.name = "[M.real_name]'s ID Card (Emergency Response Team - Medic)" + W.icon_state = "centcom" + W.access = get_all_accesses() + W.access += list(access_cent_general, access_cent_living, access_cent_medical) + M.equip_to_slot_or_del(W, slot_wear_id) + + var/obj/item/device/pda/heads/pda = new(src) + pda.owner = M.real_name + pda.ownjob = "Emergency Response Team" + pda.name = "PDA-[M.real_name] ([pda.ownjob])" + pda.icon_state = "pda-medical" + M.equip_to_slot_or_del(pda, slot_wear_pda) + + M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/response_team(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/ert/medical(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/swat(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/o2(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/toxin(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/hypospray/CMO(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(M), slot_in_backpack) + + M.equip_to_slot_or_del(new /obj/item/weapon/defibrillator/compact/combat/loaded(M), slot_belt) + + M.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/adv(M), slot_r_hand) + + if("eng") + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots/advance(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves) + M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/ert/engineer(M), slot_wear_suit) + M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/industrial(M), slot_back) + M.equip_to_slot_or_del(new /obj/item/clothing/glasses/meson(M), slot_glasses) + + var/obj/item/weapon/card/id/W = new(src) + W.assignment = "Emergency Response Team" + W.registered_name = M.real_name + W.name = "[M.real_name]'s ID Card (Emergency Response Team - Engineer)" + W.icon_state = "centcom" + W.access = get_all_accesses() + W.access += list(access_cent_general, access_cent_living, access_cent_storage) + M.equip_to_slot_or_del(W, slot_wear_id) + + var/obj/item/device/pda/heads/pda = new(src) + pda.owner = M.real_name + pda.ownjob = "Emergency Response Team" + pda.name = "PDA-[M.real_name] ([pda.ownjob])" + pda.icon_state = "pda-engineer" + M.equip_to_slot_or_del(pda, slot_wear_pda) + + M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/response_team(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/ert/engineer(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/swat(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/rcd/combat(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/rcd_ammo/large(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/rcd_ammo/large(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(M), slot_in_backpack) + + M.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full/response_team(M), slot_belt) + + M.equip_to_slot_or_del(new /obj/item/weapon/storage/briefcase/inflatable(M), slot_l_hand) + +/*/mob/living/carbon/human/proc/equip_strike_team(leader_selected = 0) Old ERT equip verb. //Special radio setup equip_to_slot_or_del(new /obj/item/device/radio/headset/ert/alt(src), slot_l_ear) @@ -321,7 +489,7 @@ proc/trigger_armed_response_team(var/force = 0) L.imp_in = src L.implanted = 1 - return 1 + return 1*/ //debug verb (That is horribly coded, LEAVE THIS OFF UNLESS PRIVATELY TESTING. Seriously. /*client/verb/ResponseTeam() diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm index 93449c76156..99e6411d5f4 100644 --- a/code/game/supplyshuttle.dm +++ b/code/game/supplyshuttle.dm @@ -93,6 +93,7 @@ var/list/mechtoys = list( /obj/machinery/computer/supplycomp name = "Supply Shuttle Console" + desc = "Used to order supplies." icon = 'icons/obj/computer.dmi' icon_state = "supply" req_access = list(access_cargo) @@ -105,6 +106,7 @@ var/list/mechtoys = list( /obj/machinery/computer/ordercomp name = "Supply Ordering Console" + desc = "Used to order supplies from cargo staff." icon = 'icons/obj/computer.dmi' icon_state = "request" circuit = "/obj/item/weapon/circuitboard/ordercomp" @@ -129,9 +131,8 @@ var/list/mechtoys = list( var/comment = null /datum/controller/supply - var/processing = 1 - var/processing_interval = 300 - var/iteration = 0 + processing = 1 + //processing_interval = 300 //supply points var/points = 50 var/points_per_process = 1 @@ -151,20 +152,21 @@ var/list/mechtoys = list( New() ordernum = rand(1,9000) - //Supply shuttle ticker - handles supply point regenertion and shuttle travelling between centcomm and the station + //Supply shuttle ticker - handles supply point regeneration and shuttle travelling between centcomm and the station proc/process() for(var/typepath in (typesof(/datum/supply_packs) - /datum/supply_packs)) var/datum/supply_packs/P = new typepath() + if(P.name == "HEADER") + del(P) + continue supply_packs[P.name] = P spawn(0) - //set background = 1 - while(1) - if(processing) - iteration++ - points += points_per_process + if(processing) + iteration++ + points += points_per_process - sleep(processing_interval) + //sleep(processing_interval) //To stop things being sent to centcomm which should not be sent to centcomm. Recursively checks for these types. proc/forbidden_atoms_check(atom/A) @@ -210,21 +212,20 @@ var/list/mechtoys = list( if(slip.stamped && slip.stamped.len) //yes, the clown stamp will work. clown is the highest authority on the station, it makes sense points += points_per_slip find_slip = 0 - continue // Sell phoron - if(istype(A, /obj/item/stack/sheet/mineral/plasma)) + else if(istype(A, /obj/item/stack/sheet/mineral/plasma)) var/obj/item/stack/sheet/mineral/plasma/P = A plasma_count += P.amount // Sell platinum - if(istype(A, /obj/item/stack/sheet/mineral/platinum)) + else if(istype(A, /obj/item/stack/sheet/mineral/platinum)) var/obj/item/stack/sheet/mineral/platinum/P = A plat_count += P.amount // If you send something in a crate, centcom's keeping it! - fixes secure crates being sent to centom to open them - del(A) - del(MA) + qdel(A) + qdel(MA) if(plasma_count) points += plasma_count * points_per_plasma @@ -272,8 +273,8 @@ var/list/mechtoys = list( A:req_access += text2num(SP.access) var/list/contains - if(istype(SP,/datum/supply_packs/randomised)) - var/datum/supply_packs/randomised/SPR = SP + if(istype(SP,/datum/supply_packs/misc/randomised)) + var/datum/supply_packs/misc/randomised/SPR = SP contains = list() if(SPR.contains.len) for(var/j=1,j<=SPR.num_contained,j++) @@ -290,8 +291,16 @@ var/list/mechtoys = list( //manifest finalisation slip.info += "
    " slip.info += "CHECK CONTENTS AND STAMP BELOW THE LINE TO CONFIRM RECEIPT OF GOODS
    " - if (SP.contraband) slip.loc = null //we are out of blanks for Form #44-D Ordering Illicit Drugs. - + if(!SP.contraband) + if(istype(A, /obj/structure/closet/crate)) + var/obj/structure/closet/crate/CR = A + CR.manifest = slip + CR.update_icon() + if(istype(A, /obj/structure/largecrate)) + var/obj/structure/largecrate/LC = A + LC.manifest = slip + LC.update_icon() + else slip.loc = null //we are out of blanks for Form #44-D Ordering Illicit Drugs. shoppinglist.Cut() return @@ -348,17 +357,18 @@ var/list/mechtoys = list( temp = "Supply points: [supply_controller.points]
    " temp += "Main Menu


    " temp += "Select a category

    " - for(var/supply_group_name in all_supply_groups ) - temp += "[supply_group_name]
    " + for(var/cat in all_supply_groups ) + temp += "[get_supply_group_name(cat)]
    " else last_viewed_group = href_list["order"] + var/cat = text2num(last_viewed_group) temp = "Supply points: [supply_controller.points]
    " temp += "Back to all categories


    " - temp += "Request from: [last_viewed_group]

    " - for(var/supply_name in supply_controller.supply_packs ) - var/datum/supply_packs/N = supply_controller.supply_packs[supply_name] - if(N.hidden || N.contraband || N.group != last_viewed_group) continue //Have to send the type instead of a reference to - temp += "[supply_name] Cost: [N.cost]
    " //the obj because it would get caught by the garbage + temp += "Request from: [get_supply_group_name(cat)]

    " + for(var/supply_type in supply_controller.supply_packs ) + var/datum/supply_packs/N = supply_controller.supply_packs[supply_type] + if(N.hidden || N.contraband || N.group != cat) continue //Have to send the type instead of a reference to + temp += "[N.name] Cost: [N.cost]
    " //the obj because it would get caught by the garbage else if (href_list["doorder"]) if(world.time < reqtime) @@ -371,7 +381,7 @@ var/list/mechtoys = list( if(!istype(P)) return var/timeout = world.time + 600 - var/reason = copytext(sanitize(input(usr,"Reason:","Why do you require this item?","") as null|text),1,MAX_MESSAGE_LEN) + var/reason = sanitize(copytext(input(usr,"Reason:","Why do you require this item?","") as null|text,1,MAX_MESSAGE_LEN)) if(world.time > timeout) return if(!reason) return @@ -492,7 +502,7 @@ var/list/mechtoys = list( onclose(user, "computer") return -/obj/machinery/computer/supplycomp/attackby(I as obj, user as mob) +/obj/machinery/computer/supplycomp/attackby(I as obj, user as mob, params) if(istype(I,/obj/item/weapon/card/emag) && !hacked) user << "\blue Special supplies unlocked." hacked = 1 @@ -543,17 +553,18 @@ var/list/mechtoys = list( temp = "Supply points: [supply_controller.points]
    " temp += "Main Menu


    " temp += "Select a category

    " - for(var/supply_group_name in all_supply_groups ) - temp += "[supply_group_name]
    " + for(var/cat in all_supply_groups ) + temp += "[get_supply_group_name(cat)]
    " else last_viewed_group = href_list["order"] + var/cat = text2num(last_viewed_group) temp = "Supply points: [supply_controller.points]
    " temp += "Back to all categories


    " - temp += "Request from: [last_viewed_group]

    " - for(var/supply_name in supply_controller.supply_packs ) - var/datum/supply_packs/N = supply_controller.supply_packs[supply_name] - if((N.hidden && !hacked) || (N.contraband && !can_order_contraband) || N.group != last_viewed_group) continue //Have to send the type instead of a reference to - temp += "[supply_name] Cost: [N.cost]
    " //the obj because it would get caught by the garbage + temp += "Request from: [get_supply_group_name(cat)]

    " + for(var/supply_type in supply_controller.supply_packs ) + var/datum/supply_packs/N = supply_controller.supply_packs[supply_type] + if((N.hidden && !hacked) || (N.contraband && !can_order_contraband) || N.group != cat) continue //Have to send the type instead of a reference to + temp += "[N.name] Cost: [N.cost]
    " //the obj because it would get caught by the garbage /*temp = "Supply points: [supply_controller.points]


    Request what?

    " @@ -575,7 +586,7 @@ var/list/mechtoys = list( if(!istype(P)) return var/timeout = world.time + 600 - var/reason = copytext(sanitize(input(usr,"Reason:","Why do you require this item?","") as null|text),1,MAX_MESSAGE_LEN) + var/reason = sanitize(copytext(input(usr,"Reason:","Why do you require this item?","") as null|text,1,MAX_MESSAGE_LEN)) if(world.time > timeout) return if(!reason) return diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index ef7c9e94f17..a20fb422aeb 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -42,8 +42,8 @@ /turf/simulated/Entered(atom/A, atom/OL) - if (istype(A,/mob/living/carbon)) - var/mob/living/carbon/M = A + if (istype(A,/mob/living/carbon/human)) + var/mob/living/carbon/human/M = A if(M.lying) return if(prob(80)) dirt++ @@ -121,7 +121,7 @@ switch (src.wet) if(1) if(istype(M, /mob/living/carbon/human)) // Added check since monkeys don't have shoes - if ((M.m_intent == "run") && !(istype(M:shoes, /obj/item/clothing/shoes) && M:shoes.flags&NOSLIP)) + if ((M.m_intent == "run") && !(istype(M:shoes, /obj/item/clothing/shoes) && M.shoes.flags&NOSLIP)) M.stop_pulling() step(M, M.dir) M << "\blue You slipped on the wet floor!" @@ -131,7 +131,7 @@ else M.inertia_dir = 0 return - else if(!istype(M, (/mob/living/carbon/slime || /mob/living/carbon/human/slime)) || (M:species.bodyflags & FEET_NOSLIP)) + else if(!istype(M, (/mob/living/carbon/human/slime)) || (M.species.bodyflags & FEET_NOSLIP)) if (M.m_intent == "run") M.stop_pulling() step(M, M.dir) diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index 3691f877890..0aae7a28e69 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -457,7 +457,7 @@ turf/simulated/floor/proc/update_icon() update_icon() levelupdate() -/turf/simulated/floor/attackby(obj/item/C as obj, mob/user as mob) +/turf/simulated/floor/attackby(obj/item/C as obj, mob/user as mob, params) if(!C || !user) return 0 diff --git a/code/game/turfs/simulated/floor_types.dm b/code/game/turfs/simulated/floor_types.dm index cd139319e7e..9f1288de647 100644 --- a/code/game/turfs/simulated/floor_types.dm +++ b/code/game/turfs/simulated/floor_types.dm @@ -51,7 +51,7 @@ thermal_conductivity = 0.025 heat_capacity = 325000 -/turf/simulated/floor/engine/attackby(obj/item/weapon/C as obj, mob/user as mob) +/turf/simulated/floor/engine/attackby(obj/item/weapon/C as obj, mob/user as mob, params) if(!C) return if(!user) diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 4fbe7180941..afbcc4b74be 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -240,8 +240,10 @@ //Interactions -/turf/simulated/wall/attack_paw(mob/user as mob) - if ((M_HULK in user.mutations)) +/turf/simulated/wall/attack_paw(mob/living/user as mob) + user.changeNext_move(CLICK_CD_MELEE) + if ((HULK in user.mutations)) + user.do_attack_animation(src) if (prob(40)) usr << text("\blue You smash through the wall.") usr.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) @@ -255,6 +257,8 @@ return src.attack_hand(user) /turf/simulated/wall/attack_animal(var/mob/living/simple_animal/M) + M.changeNext_move(CLICK_CD_MELEE) + M.do_attack_animation(src) if(M.environment_smash >= 2) if(istype(src, /turf/simulated/wall/r_wall)) if(M.environment_smash == 3) @@ -269,7 +273,8 @@ return /turf/simulated/wall/attack_hand(mob/user as mob) - if (M_HULK in user.mutations) + user.changeNext_move(CLICK_CD_MELEE) + if (HULK in user.mutations) if (prob(40) || rotting) user << text("\blue You smash through the wall.") user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) @@ -290,8 +295,8 @@ src.add_fingerprint(user) return -/turf/simulated/wall/attackby(obj/item/weapon/W as obj, mob/user as mob) - +/turf/simulated/wall/attackby(obj/item/weapon/W as obj, mob/user as mob, params) + user.changeNext_move(CLICK_CD_MELEE) if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") user << "You don't have the dexterity to do this!" return diff --git a/code/game/turfs/simulated/walls_mineral.dm b/code/game/turfs/simulated/walls_mineral.dm index 0de4efd3db7..6f0e99475ab 100644 --- a/code/game/turfs/simulated/walls_mineral.dm +++ b/code/game/turfs/simulated/walls_mineral.dm @@ -68,7 +68,7 @@ radiate() ..() -/turf/simulated/wall/mineral/uranium/attackby(obj/item/weapon/W as obj, mob/user as mob) +/turf/simulated/wall/mineral/uranium/attackby(obj/item/weapon/W as obj, mob/user as mob, params) radiate() ..() @@ -83,7 +83,7 @@ walltype = "plasma" mineral = "plasma" -/turf/simulated/wall/mineral/plasma/attackby(obj/item/weapon/W as obj, mob/user as mob) +/turf/simulated/wall/mineral/plasma/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(is_hot(W) > 300)//If the temperature of the object is over 300, then ignite ignite(is_hot(W)) return @@ -139,7 +139,7 @@ else return 0 -/turf/simulated/wall/mineral/proc/attackby(obj/item/weapon/W as obj, mob/user as mob) +/turf/simulated/wall/mineral/proc/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if((mineral == "gold") || (mineral == "silver")) if(shocked) shock() diff --git a/code/game/turfs/simulated/walls_reinforced.dm b/code/game/turfs/simulated/walls_reinforced.dm index dd9736d3685..9514e9c7afd 100644 --- a/code/game/turfs/simulated/walls_reinforced.dm +++ b/code/game/turfs/simulated/walls_reinforced.dm @@ -13,7 +13,7 @@ var/d_state = 0 /turf/simulated/wall/r_wall/attack_hand(mob/user as mob) - if (M_HULK in user.mutations) + if (HULK in user.mutations) if (prob(10) || rotting) usr << text("\blue You smash through the wall.") usr.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) @@ -33,7 +33,7 @@ return -/turf/simulated/wall/r_wall/attackby(obj/item/W as obj, mob/user as mob) +/turf/simulated/wall/r_wall/attackby(obj/item/W as obj, mob/user as mob, params) if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") user << "You don't have the dexterity to do this!" diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 0979d4fc002..6768fdf3afd 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -31,7 +31,7 @@ step(user.pulling, get_dir(user.pulling.loc, src)) return -/turf/space/attackby(obj/item/C as obj, mob/user as mob) +/turf/space/attackby(obj/item/C as obj, mob/user as mob, params) if (istype(C, /obj/item/stack/rods)) var/obj/item/stack/rods/R = C diff --git a/code/game/turfs/space/transit.dm b/code/game/turfs/space/transit.dm index d84b33dbfe9..1d3bcac2384 100644 --- a/code/game/turfs/space/transit.dm +++ b/code/game/turfs/space/transit.dm @@ -2,7 +2,7 @@ var/pushdirection // push things that get caught in the transit tile this direction //Overwrite because we dont want people building rods in space. -/turf/space/transit/attackby(obj/O as obj, mob/user as mob) +/turf/space/transit/attackby(obj/O as obj, mob/user as mob, params) return /turf/space/transit/north // moving to the north diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 0a656b903fb..c84a24c12cb 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -249,8 +249,8 @@ if(old_opacity != W.opacity) //opacity has changed. Need to update surrounding lights if(W.lighting_lumcount) //unless we're being illuminated, don't bother (may be buggy, hard to test) - W.UpdateAffectingLights() - + W.UpdateAffectingLights() + if (istype(W,/turf/simulated/floor)) W.RemoveLattice() diff --git a/code/game/vehicles/spacepods/construction.dm b/code/game/vehicles/spacepods/construction.dm index c1a68f9fa2f..aac72fc0e99 100644 --- a/code/game/vehicles/spacepods/construction.dm +++ b/code/game/vehicles/spacepods/construction.dm @@ -19,7 +19,7 @@ dir = EAST -/obj/structure/spacepod_frame/attackby(obj/item/W as obj, mob/user as mob) +/obj/structure/spacepod_frame/attackby(obj/item/W as obj, mob/user as mob, params) if(!construct || !construct.action(W, user)) ..() return diff --git a/code/game/vehicles/spacepods/parts.dm b/code/game/vehicles/spacepods/parts.dm index d682ef5240c..02624769364 100644 --- a/code/game/vehicles/spacepods/parts.dm +++ b/code/game/vehicles/spacepods/parts.dm @@ -6,5 +6,5 @@ name="Space Pod Core" icon_state = "core" construction_cost = list("iron"=5000,"uranium"=1000,"plasma"=5000) - flags = FPRINT | CONDUCT + flags = CONDUCT origin_tech = "programming=2;materials=3;bluespace=2;engineering=3" \ No newline at end of file diff --git a/code/game/vehicles/spacepods/spacepod.dm b/code/game/vehicles/spacepods/spacepod.dm index 7d81ba1ebbd..4b1bba60671 100644 --- a/code/game/vehicles/spacepods/spacepod.dm +++ b/code/game/vehicles/spacepods/spacepod.dm @@ -14,8 +14,8 @@ var/mob/living/carbon/occupant var/mob/living/carbon/occupant2 //two seaters var/datum/spacepod/equipment/equipment_system - var/battery_type = "/obj/item/weapon/cell/high" - var/obj/item/weapon/cell/battery + var/battery_type = "/obj/item/weapon/stock_parts/cell/high" + var/obj/item/weapon/stock_parts/cell/battery var/datum/gas_mixture/cabin_air var/obj/machinery/portable_atmospherics/canister/internal_tank var/datum/effect/effect/system/ion_trail_follow/space_trail/ion_trail @@ -50,9 +50,9 @@ pr_int_temp_processor = new /datum/global_iterator/pod_preserve_temp(list(src)) pr_give_air = new /datum/global_iterator/pod_tank_give_air(list(src)) equipment_system = new(src) - spacepods_list += src - -/obj/spacepod/Destroy() + spacepods_list += src + +/obj/spacepod/Destroy() spacepods_list -= src ..() @@ -62,23 +62,21 @@ pod_overlays[DAMAGE] = image(icon, icon_state="pod_damage") pod_overlays[FIRE] = image(icon, icon_state="pod_fire") + overlays.Cut() + if(health <= round(initial(health)/2)) overlays += pod_overlays[DAMAGE] if(health <= round(initial(health)/4)) overlays += pod_overlays[FIRE] - else - overlays -= pod_overlays[FIRE] - else - overlays -= pod_overlays[DAMAGE] /obj/spacepod/bullet_act(var/obj/item/projectile/P) if(P.damage && !P.nodamage) deal_damage(P.damage) - + /obj/spacepod/blob_act() deal_damage(30) return - + /obj/spacepod/attack_animal(mob/living/simple_animal/user as mob) if(user.melee_damage_upper == 0) user.emote("[user.friendly] [src]") @@ -88,7 +86,7 @@ visible_message("\red [user] [user.attacktext] [src]!") user.attack_log += text("\[[time_stamp()]\] attacked [src.name]") return - + /obj/spacepod/attack_alien(mob/user as mob) deal_damage(15) playsound(src.loc, 'sound/weapons/slash.ogg', 50, 1, -1) @@ -133,6 +131,12 @@ update_icons() +/obj/spacepod/proc/repair_damage(var/repair_amount) + if(health) + health = min(initial(health), health + repair_amount) + update_icons() + + /obj/spacepod/ex_act(severity) switch(severity) if(1) @@ -154,13 +158,15 @@ if(prob(40)) deal_damage(50) -/obj/spacepod/attackby(obj/item/W as obj, mob/user as mob) +/obj/spacepod/attackby(obj/item/W as obj, mob/user as mob, params) if(iscrowbar(W)) hatch_open = !hatch_open + playsound(loc, 'sound/items/Crowbar.ogg', 50, 1) user << "You [hatch_open ? "open" : "close"] the maintenance hatch." - if(istype(W, /obj/item/weapon/cell)) + if(istype(W, /obj/item/weapon/stock_parts/cell)) if(!hatch_open) - return ..() + user << "\red The maintenance hatch is closed!" + return if(battery) user << "The pod already has a battery." return @@ -170,7 +176,8 @@ return if(istype(W, /obj/item/device/spacepod_equipment)) if(!hatch_open) - return ..() + user << "\red The maintenance hatch is closed!" + return if(!equipment_system) user << "The pod has no equipment datum, yell at pomf" return @@ -185,10 +192,27 @@ equipment_system.weapon_system = W equipment_system.weapon_system.my_atom = src return + if(istype(W, /obj/item/weapon/weldingtool)) + if(!hatch_open) + user << "\red You must open the maintenance hatch before attempting repairs." + return + var/obj/item/weapon/weldingtool/WT = W + if(!WT.isOn()) + user << "\red The welder must be on for this task." + return + if (health < initial(health)) + user << "\blue You start welding the spacepod..." + playsound(loc, 'sound/items/Welder.ogg', 50, 1) + if(do_after(user, 20)) + if(!src || !WT.remove_fuel(3, user)) return + repair_damage(10) + user << "\blue You mend some [pick("dents","bumps","damage")] with \the [WT]" + else + user << "\blue \The [src] is fully repaired!" /obj/spacepod/attack_paw(mob/user as mob) - return src.attack_hand(user) - + return src.attack_hand(user) + /obj/spacepod/attack_hand(mob/user as mob) if(!hatch_open) return ..() @@ -347,7 +371,11 @@ return if(H && H.client && H in range(1)) - if(src.occupant) + if(src.occupant && src.occupant2) + H << "[src.name] is full." + return + + if(src.occupant && !src.occupant2) if(src.occupant.ckey == H.ckey) H.visible_message("You climb over the console and drop down into the secondary seat.") H.reset_view(src) @@ -380,38 +408,53 @@ return 1 else - H.reset_view(src) - /* - H.client.perspective = EYE_PERSPECTIVE - H.client.eye = src - */ - H.stop_pulling() - H.forceMove(src) - src.occupant = H - src.add_fingerprint(H) - src.forceMove(src.loc) - //dir = dir_in - playsound(src, 'sound/machines/windowdoor.ogg', 50, 1) - return 1 + if(!src.occupant) + H.reset_view(src) + /* + H.client.perspective = EYE_PERSPECTIVE + H.client.eye = src + */ + H.stop_pulling() + H.forceMove(src) + src.occupant = H + src.add_fingerprint(H) + src.forceMove(src.loc) + //dir = dir_in + playsound(src, 'sound/machines/windowdoor.ogg', 50, 1) + return 1 + else + return else return 0 /obj/spacepod/proc/moved_other_inside(var/mob/living/carbon/human/H as mob) - H.reset_view(src) - H.stop_pulling() - H.forceMove(src) - src.occupant2 = H - src.forceMove(src.loc) - playsound(src, 'sound/machines/windowdoor.ogg', 50, 1) - return 1 + if(!src.occupant2) + H.reset_view(src) + H.stop_pulling() + H.forceMove(src) + src.occupant2 = H + src.forceMove(src.loc) + playsound(src, 'sound/machines/windowdoor.ogg', 50, 1) + return 1 + else + return /obj/spacepod/MouseDrop_T(mob/M as mob, mob/user as mob) + if(!isliving(M)) return if(M != user) if(M.stat != 0) if(allow2enter) - moved_other_inside(M) + if(!src.occupant2) + visible_message("\red [user.name] starts loading [M.name] into the pod!") + sleep(10) + moved_other_inside(M) + else if(src.occupant2 && !src.occupant) + usr << "\red You can't put a corpse into the driver's seat!" + return + else + return else return else @@ -420,6 +463,68 @@ move_inside(M, user) +/obj/spacepod/verb/move_inside() + set category = "Object" + set name = "Enter Pod" + set src in oview(1) + var/fukkendisk = usr.GetTypeInAllContents(/obj/item/weapon/disk/nuclear) + + if(usr.restrained() || usr.stat || usr.weakened || usr.stunned || usr.paralysis || usr.resting) //are you cuffed, dying, lying, stunned or other + return + + if (usr.stat || !ishuman(usr)) + return + + if(fukkendisk) + usr << "\red The nuke-disk is locking the door every time you try to open it. You get the feeling that it doesn't want to go into the spacepod." + return + + for(var/mob/living/carbon/slime/M in range(1,usr)) + if(M.Victim == usr) + usr << "You're too busy getting your life sucked out of you." + return + + if(src.occupant) + if(allow2enter) + if(!src.occupant2) + usr << "\blue You start climbing into the secondary seat." + visible_message("\blue [usr] starts to climb into [src.name].") + if(enter_after(40,usr)) + moved_inside(usr) + else + usr << "You stop entering the spacepod." + return + else + usr << "\red You can't fit!" + else + usr << "\red The door is locked!" + + else if(!src.occupant && src.occupant2) + if(allow2enter) + usr << "\blue You start climbing into the primary seat." + visible_message("\blue [usr] starts to climb into [src.name].") + if(enter_after(40,usr)) + moved_inside(usr) + else + usr << "You stop entering the spacepod." + return + else + usr << "\red The door is locked!" + + else if(!src.occupant && !src.occupant2) + visible_message("\blue [usr] starts to climb into [src.name].") + if(enter_after(40,usr)) + if(!src.occupant) + moved_inside(usr) + else if(src.occupant!=usr) + usr << "[src.occupant] was faster. Try better next time, loser." + else + usr << "You stop entering the spacepod." + return + + +/* !!OLD BROKEN SYSTEM!! - tiger + /obj/spacepod/verb/move_inside() set category = "Object" set name = "Enter Pod" @@ -434,8 +539,12 @@ return if (usr.stat || !ishuman(usr)) return + if (src.occupant) if(allow2enter) + if(src.occupant2) + usr << "\blue You can't fit!You starts climbing into the secondary seat." visible_message("\blue [usr] starts to climb into [src.name]") if(enter_after(40,usr)) @@ -490,46 +599,55 @@ usr << "You stop entering the exosuit." return +*/ + /obj/spacepod/verb/exit_pod() set name = "Exit pod" set category = "Spacepod" set src = usr.loc + if(usr != src.occupant) if(src.occupant2) if(usr != src.occupant2) return else + if(src.occupant) + src.occupant.visible_message("[src.occupant2.name] climbs out of the pod!") //Inform the remaining occupant that someone ejected. inertia_dir = 0 // engage reverse thruster and power down pod src.occupant2.loc = src.loc src.occupant2 = null - usr << "You climb out of the pod" + usr << "You climb out of the pod." + else return else + if(src.occupant2) + src.occupant2.visible_message("[src.occupant2.name] climbs out of the pod!") //Inform the remaining occupant that someone ejected. inertia_dir = 0 // engage reverse thruster and power down pod src.occupant.loc = src.loc src.occupant = null - usr << "You climb out of the pod" + usr << "You climb out of the pod." return /obj/spacepod/verb/exit_pod2() if(!src.occupant2) set hidden = 1 return + else set name = "Eject Secondary Seat" set category = "Spacepod" set src = usr.loc set hidden = 0 - if(usr.ckey == src.occupant2.ckey) + if(usr == src.occupant2) usr << "Use 'Exit Pod'" return else usr << "You eject [src.occupant2.name]." - src.occupant2.visible_message("You were ejected from the pod!") + src.occupant2.visible_message("You were ejected from the pod!") inertia_dir = 0 // engage reverse thruster and power down pod src.occupant2.loc = src.loc src.occupant2 = null @@ -540,7 +658,7 @@ set category = "Spacepod" set src = usr.loc - if(occupant2 == src) + if(occupant2 == usr) if(!allow2enter) usr << "You can't unlock the doors from your seat." return diff --git a/code/game/vehicles/vehicle.dm b/code/game/vehicles/vehicle.dm index 3ec73f3eeb9..a61015cf6d6 100644 --- a/code/game/vehicles/vehicle.dm +++ b/code/game/vehicles/vehicle.dm @@ -16,7 +16,7 @@ //var/deflect_chance = 10 //chance to deflect the incoming projectiles, hits, or lesser the effect of ex_act. //the values in this list show how much damage will pass through, not how much will be absorbed. var/list/damage_absorption = list("brute"=0.8,"fire"=1.2,"bullet"=0.9,"laser"=1,"energy"=1,"bomb"=1) - var/obj/item/weapon/cell/cell //Our power source + var/obj/item/weapon/stock_parts/cell/cell //Our power source var/state = 0 var/list/log = new var/last_message = 0 @@ -93,7 +93,7 @@ internal_tank = new /obj/machinery/portable_atmospherics/canister/air(src) return internal_tank*/ -/obj/vehicle/proc/add_cell(var/obj/item/weapon/cell/C=null) +/obj/vehicle/proc/add_cell(var/obj/item/weapon/stock_parts/cell/C=null) if(C) C.forceMove(src) cell = C @@ -182,9 +182,9 @@ mecha.loc.assume_air(leaked_gas) else del(leaked_gas) - if(mecha.hasInternalDamage(MECHA_INT_SHORT_CIRCUIT)) + /*if(mecha.hasInternalDamage(MECHA_INT_SHORT_CIRCUIT)) // LAG INDUCING - it'll keep on creating sparks if(mecha.get_charge()) mecha.spark_system.start() mecha.cell.charge -= min(20,mecha.cell.charge) - mecha.cell.maxcharge -= min(20,mecha.cell.maxcharge) + mecha.cell.maxcharge -= min(20,mecha.cell.maxcharge) */ return \ No newline at end of file diff --git a/code/game/verbs/atom_verbs.dm b/code/game/verbs/atom_verbs.dm index 34b6e2cad71..aa55f33da0a 100644 --- a/code/game/verbs/atom_verbs.dm +++ b/code/game/verbs/atom_verbs.dm @@ -29,7 +29,7 @@ return var/P = new /obj/effect/decal/point(tile) - usr.next_move = world.time + 10 + usr.changeNext_move(CLICK_CD_POINT) spawn (20) if(P) del(P) diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm index 4505663b0c4..093b139f677 100644 --- a/code/game/verbs/ooc.dm +++ b/code/game/verbs/ooc.dm @@ -10,7 +10,7 @@ var/global/normal_ooc_colour = "#002eb8" src << "Guests may not use OOC." return - msg = trim(copytext(sanitize(msg), 1, MAX_MESSAGE_LEN)) + msg = trim(sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))) if(!msg) return if(!(prefs.toggles & CHAT_OOC)) @@ -92,7 +92,7 @@ var/global/normal_ooc_colour = "#002eb8" src << "Guests may not use OOC." return - msg = trim(copytext(sanitize(msg), 1, MAX_MESSAGE_LEN)) + msg = trim(sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))) if(!msg) return if(!(prefs.toggles & CHAT_LOOC)) @@ -120,18 +120,19 @@ var/global/normal_ooc_colour = "#002eb8" log_ooc("(LOCAL) [mob.name]/[key] : [msg]") var/list/heard = get_mobs_in_view(7, src.mob) var/mob/S = src.mob - + var/display_name = S.key if(S.stat != DEAD) display_name = S.name - + // Handle non-admins for(var/mob/M in heard) if(!M.client) continue var/client/C = M.client - if (C in admins) - continue //they are handled after that + if(C in admins) + if(C.holder.rights | R_MENTOR) + continue //they are handled after that if(C.prefs.toggles & CHAT_LOOC) if(holder) @@ -141,15 +142,16 @@ var/global/normal_ooc_colour = "#002eb8" else display_name = holder.fakekey C << "LOOC: [display_name]: [msg]" - + // Now handle admins display_name = S.key if(S.stat != DEAD) display_name = "[S.name]/([S.key])" - + for(var/client/C in admins) - if(C.prefs.toggles & CHAT_LOOC) - var/prefix = "(R)LOOC" - if (C.mob in heard) - prefix = "LOOC" - C << "[prefix]: [display_name]: [msg]" + if(C.holder.rights | R_MENTOR) + if(C.prefs.toggles & CHAT_LOOC) + var/prefix = "(R)LOOC" + if (C.mob in heard) + prefix = "LOOC" + C << "[prefix]: [display_name]: [msg]" diff --git a/code/game/verbs/who.dm b/code/game/verbs/who.dm index f5d5998e24a..7cdd9579e13 100644 --- a/code/game/verbs/who.dm +++ b/code/game/verbs/who.dm @@ -77,7 +77,7 @@ num_admins_online++ - else if(R_MOD & C.holder.rights) + else if((R_MOD | R_MENTOR) & C.holder.rights) modmsg += "\t[C] is a [C.holder.rank]" if(isobserver(C.mob)) @@ -98,9 +98,9 @@ if(!C.holder.fakekey) msg += "\t[C] is a [C.holder.rank]\n" num_admins_online++ - else if (R_MOD & C.holder.rights) + else if ((R_MOD | R_MENTOR) & C.holder.rights) modmsg += "\t[C] is a [C.holder.rank]\n" num_mods_online++ - msg = "Current Admins ([num_admins_online]):\n" + msg + "\n Current Mentors ([num_mods_online]):\n" + modmsg + msg = "Current Admins ([num_admins_online]):\n" + msg + "\n Current Mods/Mentors ([num_mods_online]):\n" + modmsg src << msg diff --git a/code/global.dm b/code/global.dm index ef6a3959f2c..4859d6a2a01 100644 --- a/code/global.dm +++ b/code/global.dm @@ -81,6 +81,7 @@ var/SCRAMBLEBLOCK = 0 var/TOXICFARTBLOCK = 0 var/STRONGBLOCK = 0 var/HORNSBLOCK = 0 +var/COMICBLOCK = 0 // Powers var/SOBERBLOCK = 0 @@ -100,7 +101,7 @@ var/POLYMORPHBLOCK = 0 // /vg/ Mutations /////////////////////////////// var/LOUDBLOCK = 0 -var/WHISPERBLOCK = 0 +//var/WHISPERBLOCK = 0 var/DIZZYBLOCK = 0 @@ -193,7 +194,6 @@ var/list/reverse_dir = list(2, 1, 3, 8, 10, 9, 11, 4, 6, 5, 7, 12, 14, 13, 15, 3 var/datum/station_state/start_state = null var/datum/configuration/config = null -var/datum/sun/sun = null var/list/combatlog = list() var/list/IClog = list() @@ -327,11 +327,5 @@ var/score_dmgestkey = null // Recall time limit: 2 hours var/recall_time_limit=72000 -//added for Xenoarchaeology, might be useful for other stuff -var/global/list/alphabet_uppercase = list("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z") - -// AI controlled bots -var/global/list/aibots = list() - // Announcer intercom, because too much stuff creates an intercom for one message then hard del()s it. -var/global/obj/item/device/radio/intercom/global_announcer = new(null) \ No newline at end of file +var/global/obj/item/device/radio/intercom/global_announcer = new(null) diff --git a/code/modules/DetectiveWork/evidence.dm b/code/modules/DetectiveWork/evidence.dm index 807c6138406..e2cf4ba6931 100644 --- a/code/modules/DetectiveWork/evidence.dm +++ b/code/modules/DetectiveWork/evidence.dm @@ -13,7 +13,7 @@ return evidencebagEquip(I, user) -/obj/item/weapon/evidencebag/attackby(obj/item/I, mob/user) +/obj/item/weapon/evidencebag/attackby(obj/item/I, mob/user, params) if(evidencebagEquip(I, user)) return 1 diff --git a/code/modules/DetectiveWork/footprints_and_rag.dm b/code/modules/DetectiveWork/footprints_and_rag.dm index 04df3a507e6..8b0cbcbe305 100644 --- a/code/modules/DetectiveWork/footprints_and_rag.dm +++ b/code/modules/DetectiveWork/footprints_and_rag.dm @@ -25,7 +25,7 @@ possible_transfer_amounts = list(5) volume = 5 can_be_placed_into = null - flags = FPRINT | TABLEPASS | OPENCONTAINER | NOBLUDGEON + flags = OPENCONTAINER | NOBLUDGEON /obj/item/weapon/reagent_containers/glass/rag/attack(atom/target as obj|turf|area, mob/user as mob , flag) if(ismob(target) && target.reagents && reagents.total_volume) diff --git a/code/modules/DetectiveWork/scanner.dm b/code/modules/DetectiveWork/scanner.dm index 38c65445bb0..d694e4c1645 100644 --- a/code/modules/DetectiveWork/scanner.dm +++ b/code/modules/DetectiveWork/scanner.dm @@ -8,7 +8,7 @@ icon_state = "forensic1" w_class = 3.0 item_state = "electronic" - flags = FPRINT | TABLEPASS | CONDUCT | NOBLUDGEON + flags = CONDUCT | NOBLUDGEON slot_flags = SLOT_BELT var/scanning = 0 var/list/log = list() diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm index fcf219db147..f0fa25224b5 100644 --- a/code/modules/admin/DB ban/functions.dm +++ b/code/modules/admin/DB ban/functions.dm @@ -307,7 +307,11 @@ datum/admins/proc/DB_ban_unban_by_id(var/id) output += "" for(var/j in nonhuman_positions) output += "" - for(var/j in list("traitor","changeling","operative","revolutionary","cultist","wizard")) + for(var/j in list("Dionaea","NPC","AntagHUD","Emergency Response Team")) + output += "" + for(var/j in list("commanddept","securitydept","engineeringdept","medicaldept","sciencedept","supportdept","nonhumandept")) + output += "" + for(var/j in list("Syndicate","traitor","changeling","operative","revolutionary","cultist","wizard","alien","ninja","raider","mutineer","blob")) output += "" output += "
    Transmit:[(!radio.isWireCut(WIRE_TRANSMIT)) ? "En" : "Dis" ]abled + [radio.broadcasting ? "En" : "Dis" ]abled
    Receive:[(!radio.isWireCut(WIRE_RECEIVE)) ? "En" : "Dis" ]abled - -
    Signal Pulser:[(!radio.isWireCut(WIRE_SIGNAL)) ? "En" : "Dis" ]abled + [radio.listening ? "En" : "Dis" ]abled
    " output += "Reason:

    " diff --git a/code/modules/admin/NewBan.dm b/code/modules/admin/NewBan.dm index 035b2d23096..ecc2a812bf0 100644 --- a/code/modules/admin/NewBan.dm +++ b/code/modules/admin/NewBan.dm @@ -119,6 +119,10 @@ var/savefile/Banlist Banlist["temp"] << temp if (temp) Banlist["minutes"] << bantimestamp + if(!temp) + notes_add(ckey, "Permanently banned - [reason]") + else + notes_add(ckey, "Banned for [minutes] minutes - [reason]") return 1 /proc/RemoveBan(foldername) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index f4b35c40ba2..c6fb5508ea0 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -781,7 +781,7 @@ var/global/nologevent = 0 /datum/admins/proc/unprison(var/mob/M in mob_list) set category = "Admin" set name = "Unprison" - if (M.z == 2) + if ((M.z in config.admin_levels)) M.loc = pick(latejoin) message_admins("[key_name_admin(usr)] has unprisoned [key_name_admin(M)]", 1) log_admin("[key_name(usr)] has unprisoned [key_name(M)]") @@ -956,6 +956,16 @@ proc/move_gamma_ship() fromArea = locate(/area/shuttle/gamma/station) toArea = locate(/area/shuttle/gamma/space) fromArea.move_contents_to(toArea) + + for(var/obj/machinery/mech_bay_recharge_port/P in toArea) + P.locate_recharge_turf() + + for(var/obj/machinery/power/apc/A in toArea) + A.init() + + for(var/obj/machinery/alarm/A in toArea) + A.first_run() + if (gamma_ship_location) gamma_ship_location = 0 else diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index a9afe87debf..d9f5d7d54ba 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -41,6 +41,7 @@ var/list/admin_ranks = list() //list of all ranks with associated rights if("sound","sounds") rights |= R_SOUNDS if("spawn","create") rights |= R_SPAWN if("mod") rights |= R_MOD + if("mentor") rights |= R_MENTOR admin_ranks[rank] = rights previous_rights = rights diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 727dfc58c61..6a7ee186c40 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -2,10 +2,9 @@ var/list/admin_verbs_default = list( // /datum/admins/proc/show_player_panel, /*shows an interface for individual players, with various links (links require additional flags*/ /client/proc/deadmin_self, /*destroys our own admin datum so we can play as a regular player*/ - /client/proc/debug_variables, /*allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify*/ // /client/proc/check_antagonists, /*shows all antags*/ - /client/proc/cmd_mentor_check_new_players // /client/proc/deadchat /*toggles deadchat on/off*/ + /client/proc/cmd_mentor_check_new_players ) var/list/admin_verbs_admin = list( /client/proc/check_antagonists, /*shows all antags*/ @@ -44,9 +43,8 @@ var/list/admin_verbs_admin = list( /client/proc/admin_memo, /*admin memo system. show/delete/write. +SERVER needed to delete admin memos of others*/ /client/proc/dsay, /*talk in deadchat using our ckey/fakekey*/ /client/proc/toggleprayers, /*toggles prayers on/off*/ -// /client/proc/toggle_hear_radio, /*toggles whether we hear the radio*/ + /client/proc/toggle_hear_radio, /*toggles whether we hear the radio*/ /client/proc/investigate_show, /*various admintools for investigation. Such as a singulo grief-log*/ - /client/proc/secrets, /datum/admins/proc/toggleooc, /*toggles ooc on/off for everyone*/ /datum/admins/proc/toggleoocdead, /*toggles ooc on/off for everyone who is dead*/ /datum/admins/proc/toggledsay, /*toggles dsay on/off for everyone*/ @@ -56,7 +54,6 @@ var/list/admin_verbs_admin = list( /client/proc/cmd_mod_say, /datum/admins/proc/show_player_info, /client/proc/free_slot, /*frees slot for chosen job*/ - /client/proc/cmd_admin_rejuvenate, /client/proc/toggleattacklogs, /client/proc/toggledebuglogs, /client/proc/update_mob_sprite, @@ -64,8 +61,10 @@ var/list/admin_verbs_admin = list( /client/proc/man_up, /client/proc/global_man_up, /client/proc/delbook, - /client/proc/event_manager_panel, - /client/proc/empty_ai_core_toggle_latejoin + /client/proc/empty_ai_core_toggle_latejoin, + /client/proc/freeze, + /client/proc/freezemecha + ) var/list/admin_verbs_ban = list( /client/proc/unban_panel, @@ -98,6 +97,9 @@ var/list/admin_verbs_event = list( /client/proc/cmd_admin_world_narrate, /*sends text to all players with no padding*/ /client/proc/response_team, // Response Teams admin verb /client/proc/cmd_admin_create_centcom_report, + /client/proc/fax_panel, + /client/proc/secrets, + /client/proc/event_manager_panel ) var/list/admin_verbs_spawn = list( @@ -122,21 +124,7 @@ var/list/admin_verbs_server = list( /client/proc/delbook, /client/proc/toggle_antagHUD_use, /client/proc/toggle_antagHUD_restrictions, - /client/proc/set_ooc, - - //Doubling of certain event verbs for senior admins - /datum/admins/proc/access_news_network, /*allows access of newscasters*/ - /client/proc/cmd_admin_direct_narrate, /*send text directly to a player with no padding. Useful for narratives and fluff-text*/ - /client/proc/cmd_admin_world_narrate, /*sends text to all players with no padding*/ - /client/proc/toggle_random_events, - /client/proc/toggle_ert_calling, - /client/proc/one_click_antag, - /client/proc/cmd_admin_change_custom_event, - /client/proc/cmd_admin_create_centcom_report, - /client/proc/cmd_admin_dress, - /client/proc/editappear, - /client/proc/response_team, // Response Teams admin verb - /client/proc/nanomapgen_DumpImage + /client/proc/set_ooc ) var/list/admin_verbs_debug = list( /client/proc/cmd_admin_list_open_jobs, @@ -156,7 +144,8 @@ var/list/admin_verbs_debug = list( /client/proc/callproc, /client/proc/callproc_datum, /client/proc/toggledebuglogs, - /client/proc/qdel_toggle // /vg/ + /client/proc/qdel_toggle, // /vg/ + /client/proc/gc_dump_hdl ) var/list/admin_verbs_possess = list( /proc/possess, @@ -166,7 +155,8 @@ var/list/admin_verbs_permissions = list( /client/proc/edit_admin_permissions ) var/list/admin_verbs_rejuv = list( - /client/proc/respawn_character + /client/proc/respawn_character, + /client/proc/cmd_admin_rejuvenate ) var/list/admin_verbs_mod = list( /client/proc/cmd_admin_pm_context, /*right-click adminPM interface*/ @@ -181,9 +171,15 @@ var/list/admin_verbs_mod = list( /client/proc/dsay, /datum/admins/proc/show_player_panel, /client/proc/jobbans, + /client/proc/debug_variables /*allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify*/ // /client/proc/cmd_admin_subtle_message /*send an message to somebody as a 'voice in their head'*/ ) +var/list/admin_verbs_mentor = list( + /client/proc/cmd_admin_pm_context, /*right-click adminPM interface*/ + /client/proc/cmd_admin_pm_panel, /*admin-pm list*/ + /client/proc/cmd_admin_pm_by_key_panel /*admin-pm list by key*/ +) /client/proc/add_admin_verbs() if(holder) @@ -201,6 +197,7 @@ var/list/admin_verbs_mod = list( if(holder.rights & R_SOUNDS) verbs += admin_verbs_sounds if(holder.rights & R_SPAWN) verbs += admin_verbs_spawn if(holder.rights & R_MOD) verbs += admin_verbs_mod + if(holder.rights & R_MENTOR) verbs += admin_verbs_mentor /client/proc/admin_ghost() set category = "Admin" @@ -637,6 +634,7 @@ var/list/admin_verbs_mod = list( set category = "Preferences" prefs.toggles ^= CHAT_ATTACKLOGS + prefs.save_preferences(src) if (prefs.toggles & CHAT_ATTACKLOGS) usr << "You now will get attack log messages" else diff --git a/code/modules/admin/create_object.dm b/code/modules/admin/create_object.dm index 5b5f926e4b1..5b5ee047852 100644 --- a/code/modules/admin/create_object.dm +++ b/code/modules/admin/create_object.dm @@ -15,7 +15,7 @@ var/quick_create_object_html = null var/pathtext = null - pathtext = input("Select the path of the object you wish to create.", "Path", "/obj") in list("/obj","/obj/structure","/obj/item","/obj/item/weapon","/obj/machinery") + pathtext = input("Select the path of the object you wish to create.", "Path", "/obj") in list("/obj","/obj/structure","/obj/item","/obj/item/weapon","/obj/item/clothing","/obj/machinery","/obj/mecha") var path = text2path(pathtext) diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index 4a2c8fcf0d6..33fc2240830 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -49,21 +49,21 @@ proc/admin_proc() NOTE: it checks usr! not src! So if you're checking somebody's rank in a proc which they did not call you will have to do something like if(client.holder.rights & R_ADMIN) yourself. */ -/proc/check_rights(rights_required, show_msg=1) - if(usr && usr.client) +/proc/check_rights(rights_required, show_msg=1, var/mob/user = usr) + if(user && user.client) if(rights_required) - if(usr.client.holder) - if(rights_required & usr.client.holder.rights) + if(user.client.holder) + if(rights_required & user.client.holder.rights) return 1 else if(show_msg) - usr << "Error: You do not have sufficient rights to do that. You require one of the following flags:[rights2text(rights_required," ")]." + user << "Error: You do not have sufficient rights to do that. You require one of the following flags:[rights2text(rights_required," ")]." else - if(usr.client.holder) + if(user.client.holder) return 1 else if(show_msg) - usr << "Error: You are not an admin." + user << "Error: You are not an admin." return 0 //probably a bit iffy - will hopefully figure out a better solution diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 082553f3092..49274720ed1 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -455,6 +455,16 @@ dat += "[mob_loc.loc]" else dat += "Head not found!" + if(ticker.mode.num_players_started() >= 30) + for(var/datum/mind/N in ticker.mode.get_extra_living_heads()) + var/mob/M = N.current + if(M) + dat += "[M.real_name][M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""]" + dat += "PM" + var/turf/mob_loc = get_turf_loc(M) + dat += "[mob_loc.loc]" + else + dat += "Head not found!" dat += "" if(ticker.mode.name == "nations") diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 4388c0a8247..952b939cfc6 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -37,18 +37,10 @@ if(!src.makeWizard()) usr << "\red Unfortunately there weren't enough candidates available." if("7") - log_admin("[key_name(usr)] has spawned a nuke team.") - if(!src.makeNukeTeam()) + log_admin("[key_name(usr)] has spawned vampires.") + if(!src.makeVampires()) usr << "\red Unfortunately there weren't enough candidates available." if("8") - log_admin("[key_name(usr)] has spawned a ninja.") - src.makeSpaceNinja() - if("9") - log_admin("[key_name(usr)] has spawned aliens.") - src.makeAliens() - if("10") - log_admin("[key_name(usr)] has spawned a death squad.") - if("11") log_admin("[key_name(usr)] has spawned vox raiders.") if(!src.makeVoxRaiders()) usr << "\red Unfortunately there weren't enough candidates available." @@ -287,28 +279,28 @@ message_admins("\blue [key_name_admin(usr)] has used rudimentary transformation on [key_name_admin(M)]. Transforming to [href_list["simplemake"]]; deletemob=[delmob]", 1) switch(href_list["simplemake"]) - if("observer") M.change_mob_type( /mob/dead/observer , null, null, delmob ) - if("drone") M.change_mob_type( /mob/living/carbon/alien/humanoid/drone , null, null, delmob ) - if("hunter") M.change_mob_type( /mob/living/carbon/alien/humanoid/hunter , null, null, delmob ) - if("queen") M.change_mob_type( /mob/living/carbon/alien/humanoid/queen/large , null, null, delmob ) - if("sentinel") M.change_mob_type( /mob/living/carbon/alien/humanoid/sentinel , null, null, delmob ) - if("larva") M.change_mob_type( /mob/living/carbon/alien/larva , null, null, delmob ) - if("human") M.change_mob_type( /mob/living/carbon/human/human , null, null, delmob ) - if("slime") M.change_mob_type( /mob/living/carbon/slime , null, null, delmob ) - if("monkey") M.change_mob_type( /mob/living/carbon/monkey , null, null, delmob ) - if("robot") M.change_mob_type( /mob/living/silicon/robot , null, null, delmob ) - if("cat") M.change_mob_type( /mob/living/simple_animal/cat , null, null, delmob ) - if("runtime") M.change_mob_type( /mob/living/simple_animal/cat/Runtime , null, null, delmob ) - if("corgi") M.change_mob_type( /mob/living/simple_animal/corgi , null, null, delmob ) - if("ian") M.change_mob_type( /mob/living/simple_animal/corgi/Ian , null, null, delmob ) - if("crab") M.change_mob_type( /mob/living/simple_animal/crab , null, null, delmob ) - if("coffee") M.change_mob_type( /mob/living/simple_animal/crab/Coffee , null, null, delmob ) - if("parrot") M.change_mob_type( /mob/living/simple_animal/parrot , null, null, delmob ) - if("polyparrot") M.change_mob_type( /mob/living/simple_animal/parrot/Poly , null, null, delmob ) - if("constructarmoured") M.change_mob_type( /mob/living/simple_animal/construct/armoured , null, null, delmob ) - if("constructbuilder") M.change_mob_type( /mob/living/simple_animal/construct/builder , null, null, delmob ) - if("constructwraith") M.change_mob_type( /mob/living/simple_animal/construct/wraith , null, null, delmob ) - if("shade") M.change_mob_type( /mob/living/simple_animal/shade , null, null, delmob ) + if("observer") M.change_mob_type( /mob/dead/observer , null, null, delmob, 1 ) + if("drone") M.change_mob_type( /mob/living/carbon/alien/humanoid/drone , null, null, delmob, 1 ) + if("hunter") M.change_mob_type( /mob/living/carbon/alien/humanoid/hunter , null, null, delmob, 1 ) + if("queen") M.change_mob_type( /mob/living/carbon/alien/humanoid/queen/large , null, null, delmob, 1 ) + if("sentinel") M.change_mob_type( /mob/living/carbon/alien/humanoid/sentinel , null, null, delmob, 1 ) + if("larva") M.change_mob_type( /mob/living/carbon/alien/larva , null, null, delmob, 1 ) + if("human") M.change_mob_type( /mob/living/carbon/human/human , null, null, delmob, 1 ) + if("slime") M.change_mob_type( /mob/living/carbon/slime , null, null, delmob, 1 ) + if("monkey") M.change_mob_type( /mob/living/carbon/monkey , null, null, delmob, 1 ) + if("robot") M.change_mob_type( /mob/living/silicon/robot , null, null, delmob, 1 ) + if("cat") M.change_mob_type( /mob/living/simple_animal/cat , null, null, delmob, 1 ) + if("runtime") M.change_mob_type( /mob/living/simple_animal/cat/Runtime , null, null, delmob, 1 ) + if("corgi") M.change_mob_type( /mob/living/simple_animal/corgi , null, null, delmob, 1 ) + if("ian") M.change_mob_type( /mob/living/simple_animal/corgi/Ian , null, null, delmob, 1 ) + if("crab") M.change_mob_type( /mob/living/simple_animal/crab , null, null, delmob, 1 ) + if("coffee") M.change_mob_type( /mob/living/simple_animal/crab/Coffee , null, null, delmob, 1 ) + if("parrot") M.change_mob_type( /mob/living/simple_animal/parrot , null, null, delmob, 1 ) + if("polyparrot") M.change_mob_type( /mob/living/simple_animal/parrot/Poly , null, null, delmob, 1 ) + if("constructarmoured") M.change_mob_type( /mob/living/simple_animal/construct/armoured , null, null, delmob, 1 ) + if("constructbuilder") M.change_mob_type( /mob/living/simple_animal/construct/builder , null, null, delmob, 1 ) + if("constructwraith") M.change_mob_type( /mob/living/simple_animal/construct/wraith , null, null, delmob, 1 ) + if("shade") M.change_mob_type( /mob/living/simple_animal/shade , null, null, delmob, 1 ) /////////////////////////////////////new ban stuff @@ -599,13 +591,13 @@ if(counter >= 5) //So things dont get squiiiiished! jobs += "" counter = 0 - + //Drone if(jobban_isbanned(M, "Drone")) jobs += "Drone" else jobs += "Drone" - + //pAI if(jobban_isbanned(M, "pAI")) jobs += "pAI" @@ -675,19 +667,19 @@ jobs += "[replacetext("Ninja", " ", " ")]" else jobs += "[replacetext("Ninja", " ", " ")]" - + //Raider if(jobban_isbanned(M, "raider") || isbanned_dept) jobs += "[replacetext("Raider", " ", " ")]" else jobs += "[replacetext("Raider", " ", " ")]" - + //Mutineer if(jobban_isbanned(M, "mutineer") || isbanned_dept) jobs += "[replacetext("Mutineer", " ", " ")]" else jobs += "[replacetext("Mutineer", " ", " ")]" - + //Blob if(jobban_isbanned(M, "blob") || isbanned_dept) jobs += "[replacetext("Blob", " ", " ")]" @@ -706,12 +698,12 @@ jobs += "Dionaea Nymph" else jobs += "Dionaea Nymph" - + //NPC if(jobban_isbanned(M, "NPC")) jobs += "NPC" else - jobs += "NPC" + jobs += "NPC" //ANTAG HUD if(jobban_isbanned(M, "AntagHUD")) @@ -1100,6 +1092,7 @@ message_admins("\blue [key_name_admin(usr)] attempting to monkeyize [key_name_admin(H)]", 1) H.monkeyize() + else if(href_list["corgione"]) if(!check_rights(R_SPAWN)) return @@ -1149,7 +1142,7 @@ //strip their stuff and stick it in the crate for(var/obj/item/I in M) - M.u_equip(I) + M.unEquip(I) if(I) I.loc = locker I.layer = initial(I.layer) @@ -1170,7 +1163,7 @@ M << "\red You have been sent to the prison station!" log_admin("[key_name(usr)] sent [key_name(M)] to the prison station.") message_admins("\blue [key_name_admin(usr)] sent [key_name_admin(M)] to the prison station.", 1) - + else if(href_list["sendbacktolobby"]) if(!check_rights(R_ADMIN)) return @@ -1193,7 +1186,7 @@ var/mob/new_player/NP = new() NP.ckey = M.ckey - qdel(M) + qdel(M) else if(href_list["tdome1"]) if(!check_rights(R_SERVER|R_EVENT)) return @@ -1210,7 +1203,7 @@ return for(var/obj/item/I in M) - M.u_equip(I) + M.unEquip(I) if(I) I.loc = M.loc I.layer = initial(I.layer) @@ -1239,7 +1232,7 @@ return for(var/obj/item/I in M) - M.u_equip(I) + M.unEquip(I) if(I) I.loc = M.loc I.layer = initial(I.layer) @@ -1290,7 +1283,7 @@ return for(var/obj/item/I in M) - M.u_equip(I) + M.unEquip(I) if(I) I.loc = M.loc I.layer = initial(I.layer) @@ -1437,7 +1430,7 @@ foo += text("Is an AI | ") else foo += text("Make AI | ", src, M) - if(M.z != 2) + if(!(M.z in config.admin_levels)) foo += text("Prison | ", src, M) foo += text("Maze | ", src, M) else @@ -1569,11 +1562,11 @@ usr << "This can only be used on instances of type /mob/living" return - if(alert(src.owner, "Are you sure you wish to hit [key_name(M)] with Blue Space Artillery?", "Confirm Firing?" , "Yes" , "No") != "Yes") + if(alert(src.owner, "Are you sure you wish to hit [key_name(M)] with Bluespace Artillery?", "Confirm Firing?" , "Yes" , "No") != "Yes") return if(BSACooldown) - src.owner << "Standby! Reload cycle in progress! Gunnary crews ready in five seconds!" + src.owner << "Standby. Reload cycle in progress. Gunnery crews ready in five seconds!" return BSACooldown = 1 @@ -1605,6 +1598,9 @@ M.stuttering = 20 else if(href_list["CentcommReply"]) + if(!check_rights(R_ADMIN)) + return + var/mob/living/carbon/human/H = locate(href_list["CentcommReply"]) if(!istype(H)) usr << "This can only be used on instances of type /mob/living/carbon/human" @@ -1622,10 +1618,16 @@ H << "You hear something crackle in your headset for a moment before a voice speaks. \"Please stand by for a message from Central Command. Message as follows. [input]. Message ends.\"" else if(href_list["SyndicateReply"]) + if(!check_rights(R_ADMIN)) + return + var/mob/living/carbon/human/H = locate(href_list["SyndicateReply"]) if(!istype(H)) usr << "This can only be used on instances of type /mob/living/carbon/human" return + if(H.stat != 0) + usr << "The person you are trying to contact is not conscious." + return if(!istype(H.l_ear, /obj/item/device/radio/headset) && !istype(H.r_ear, /obj/item/device/radio/headset)) usr << "The person you are trying to contact is not wearing a headset" return @@ -1654,6 +1656,9 @@ H << "You hear something crackle in your headset for a moment before a voice speaks. \"Please stand by for a message from your HONKbrothers. Message as follows, HONK. [input]. Message ends, HONK.\"" else if(href_list["AdminFaxView"]) + if(!check_rights(R_ADMIN)) + return + var/obj/item/fax = locate(href_list["AdminFaxView"]) if (istype(fax, /obj/item/weapon/paper)) var/obj/item/weapon/paper/P = fax @@ -1666,21 +1671,24 @@ //open a browse window listing the contents instead var/data = "" var/obj/item/weapon/paper_bundle/B = fax - + for (var/page = 1, page <= B.amount + 1, page++) var/obj/pageobj = B.contents[page] data += "Page [page] - [pageobj.name]
    " - + usr << browse(data, "window=[B.name]") else usr << "\red The faxed item is not viewable. This is probably a bug, and should be reported on the tracker: [fax.type]" else if (href_list["AdminFaxViewPage"]) + if(!check_rights(R_ADMIN)) + return + var/page = text2num(href_list["AdminFaxViewPage"]) var/obj/item/weapon/paper_bundle/bundle = locate(href_list["paper_bundle"]) - + if (!bundle) return - + if (istype(bundle.contents[page], /obj/item/weapon/paper)) var/obj/item/weapon/paper/P = bundle.contents[page] P.show_content(src.owner, 1) @@ -1688,52 +1696,156 @@ var/obj/item/weapon/photo/H = bundle.contents[page] H.show(src.owner) return - - else if(href_list["CentcommFaxReply"]) - var/mob/sender = locate(href_list["CentcommFaxReply"]) + + else if(href_list["AdminFaxCreate"]) + if(!check_rights(R_ADMIN)) + return + + var/mob/sender = locate(href_list["AdminFaxCreate"]) var/obj/machinery/photocopier/faxmachine/fax = locate(href_list["originfax"]) + var/faxtype = href_list["faxtype"] + var/reply_to = locate(href_list["replyto"]) + var/destination + var/notify - var/input = input(src.owner, "Please enter a message to reply to [key_name(sender)] via secure connection. NOTE: BBCode does not work, but HTML tags do! Use
    for line breaks.", "Outgoing message from Centcomm", "") as message|null - if(!input) return + var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(null) //hopefully the null loc won't cause trouble for us + + if(!fax) + var/list/departmentoptions = alldepartments + "All Departments" + destination = input(usr, "To which department?", "Choose a department", "") as null|anything in departmentoptions + if(!destination) + del(P) + return + + for(var/obj/machinery/photocopier/faxmachine/F in allfaxes) + if(destination != "All Departments" && F.department == destination) + fax = F + + + var/input = input(src.owner, "Please enter a message to send a fax via secure connection. Use
    for line breaks. Both pencode and HTML work.", "Outgoing message from Centcomm", "") as message|null + if(!input) + del(P) + return + input = P.parsepencode(input) // Encode everything from pencode to html + + var/customname = input(src.owner, "Pick a title for the fax.", "Fax Title") as text|null + if(!customname) + customname = "paper" + + var/stampname + var/stamptype + var/stampvalue + var/sendername + switch(faxtype) + if("Central Command") + stamptype = "icon" + stampvalue = "cent" + sendername = command_name() + if("Syndicate") + sendername = "UNKNOWN" + if("Administrator") + stamptype = input(src.owner, "Pick a stamp type.", "Stamp Type") as null|anything in list("icon","text","none") + if(stamptype == "icon") + stampname = input(src.owner, "Pick a stamp icon.", "Stamp Icon") as null|anything in list("centcom","granted","denied","clown") + switch(stampname) + if("centcom") + stampvalue = "cent" + if("granted") + stampvalue = "ok" + if("denied") + stampvalue = "deny" + if("clown") + stampvalue = "clown" + else if(stamptype == "text") + stampvalue = input(src.owner, "What should the stamp say?", "Stamp Text") as text|null + else if(stamptype == "none") + stamptype = "" + else + del(P) + return + + sendername = input(src.owner, "What organization does the fax come from? This determines the prefix of the paper (i.e. Central Command- Title). This is optional.", "Organization") as text|null + + if(sender) + notify = alert(src.owner, "Would you like to inform the original sender that a fax has arrived?","Notify Sender","Yes","No") - var/customname = input(src.owner, "Pick a title for the report", "Title") as text|null - // Create the reply message - var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( null ) //hopefully the null loc won't cause trouble for us - P.name = "[command_name()]- [customname]" + if(sendername) + P.name = "[sendername]- [customname]" + else + P.name = "[customname]" P.info = input P.update_icon() - P.stamps += "
    " - var/image/stampoverlay = image('icons/obj/bureaucracy.dmi') P.x = rand(-2, 0) - P.y = rand(-1, 2) + P.y = rand(-1, 2) P.offset_x += P.x P.offset_y += P.y - stampoverlay.pixel_x = P.x - stampoverlay.pixel_y = P.y - - if(!P.ico) - P.ico = new - P.ico += "paper_stamp-cent" - stampoverlay.icon_state = "paper_stamp-cent" - - // Stamps - if(!P.stamped) - P.stamped = new - P.stamped += /obj/item/weapon/stamp/centcom - P.overlays += stampoverlay + if(stamptype) + var/image/stampoverlay = image('icons/obj/bureaucracy.dmi') + stampoverlay.pixel_x = P.x + stampoverlay.pixel_y = P.y - if(fax.recievefax(P)) - src.owner << "\blue Message reply to transmitted successfully." - log_admin("[key_name(src.owner)] replied to a fax message from [key_name(sender)]: [input]") - message_admins("[key_name_admin(src.owner)] replied to a fax message from [key_name_admin(sender)]", 1) + if(!P.ico) + P.ico = new + P.ico += "paper_stamp-[stampvalue]" + stampoverlay.icon_state = "paper_stamp-[stampvalue]" + + if(stamptype == "icon") + if(!P.stamped) + P.stamped = new + P.stamped += /obj/item/weapon/stamp/centcom + P.overlays += stampoverlay + P.stamps += "
    " + + else if(stamptype == "text") + if(!P.stamped) + P.stamped = new + P.stamped += /obj/item/weapon/stamp + P.overlays += stampoverlay + P.stamps += "
    [stampvalue]" + + if(destination != "All Departments") + if(!fax.receivefax(P)) + src.owner << "\red Message transmission failed." + return else - src.owner << "\red Message reply failed." - - spawn(100) - del(P) + for(var/obj/machinery/photocopier/faxmachine/F in allfaxes) + if((F.z in config.station_levels)) + if(!F.receivefax(P)) + src.owner << "\red Message transmission to [F.department] failed." + + var/datum/fax/admin/A = new /datum/fax/admin() + A.name = P.name + A.from_department = faxtype + if(destination != "All Departments") + A.to_department = fax.department + else + A.to_department = "All Departments" + A.origin = "Administrator" + A.message = P + A.reply_to = reply_to + A.sent_by = usr + A.sent_at = world.time + + src.owner << "\blue Message transmitted successfully." + if(notify == "Yes") + var/mob/living/carbon/human/H = sender + if(istype(H) && H.stat == 1 && (istype(H.l_ear, /obj/item/device/radio/headset) || istype(H.r_ear, /obj/item/device/radio/headset))) + sender << "Your headset pings, notifying you that a reply to your fax has arrived." + if(sender) + log_admin("[key_name(src.owner)] replied to a fax message from [key_name(sender)]: [input]") + message_admins("[key_name_admin(src.owner)] replied to a fax message from [key_name_admin(sender)] (VIEW).", 1) + else + log_admin("[key_name(src.owner)] sent a fax message to [destination]: [input]") + message_admins("[key_name_admin(src.owner)] sent a fax message to [destination] (VIEW).", 1) return + else if(href_list["refreshfaxpanel"]) + if(!check_rights(R_ADMIN)) + return + + fax_panel(usr) + else if(href_list["jumpto"]) if(!check_rights(R_ADMIN)) return @@ -1992,11 +2104,11 @@ if(gravity_is_on) log_admin("[key_name(usr)] toggled gravity on.", 1) message_admins("\blue [key_name_admin(usr)] toggled gravity on.", 1) - command_alert("Gravity generators are again functioning within normal parameters. Sorry for any inconvenience.") + command_announcement.Announce("Gravity generators are again functioning within normal parameters. Sorry for any inconvenience.") else log_admin("[key_name(usr)] toggled gravity off.", 1) message_admins("\blue [key_name_admin(usr)] toggled gravity off.", 1) - command_alert("Feedback surge detected in mass-distributions systems. Artifical gravity has been disabled whilst the system reinitializes. Further failures may result in a gravitational collapse and formation of blackholes. Have a nice day.") + command_announcement.Announce("Feedback surge detected in mass-distributions systems. Artifical gravity has been disabled whilst the system reinitializes. Further failures may result in a gravitational collapse and formation of blackholes. Have a nice day.") if("wave") feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","Meteor") @@ -2033,12 +2145,12 @@ feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","BLOB") message_admins("[key_name_admin(usr)] has triggered a blob.") - new /datum/game_mode/blob() + new /datum/game_mode/blob() if("aliens") feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","ALIEN") message_admins("[key_name_admin(usr)] has triggered an alien infestation.") - new /datum/event/alien_infestation() + new /datum/event/alien_infestation() if("power") feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","P") @@ -2095,7 +2207,7 @@ for(var/mob/living/carbon/human/H in mob_list) var/turf/loc = find_loc(H) var/security = 0 - if(loc.z > 1 || prisonwarped.Find(H)) + if(!(loc.z in config.station_levels) || prisonwarped.Find(H)) //don't warp them if they aren't ready or are already there continue @@ -2111,7 +2223,7 @@ if(istype(W, /datum/organ/external)) continue //don't strip organs - H.u_equip(W) + H.unEquip(W) if (H.client) H.client.screen -= W if (W) @@ -2130,7 +2242,7 @@ if(!ticker) alert("The game hasn't started yet!") return - var/objective = copytext(sanitize(input("Enter an objective")),1,MAX_MESSAGE_LEN) + var/objective = sanitize(copytext(input("Enter an objective"),1,MAX_MESSAGE_LEN)) if(!objective) return feedback_inc("admin_secrets_fun_used",1) @@ -2408,7 +2520,7 @@ message_admins("[key_name_admin(usr)] made the floor LAVA! It'll last [length] seconds and it will deal [damage] damage to everyone.", 1) for(var/turf/simulated/floor/F in world) - if(F.z == 1) + if((F.z in config.station_levels)) F.name = "lava" F.desc = "The floor is LAVA!" F.overlays += "lava" @@ -2433,7 +2545,7 @@ sleep(10) for(var/turf/simulated/floor/F in world) // Reset everything. - if(F.z == 1) + if((F.z in config.station_levels)) F.name = initial(F.name) F.desc = initial(F.desc) F.overlays.Cut() @@ -2481,11 +2593,10 @@ feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","EgL") for(var/obj/machinery/door/airlock/W in world) - if(W.z == 1 && !istype(get_area(W), /area/bridge) && !istype(get_area(W), /area/crew_quarters) && !istype(get_area(W), /area/security/prison)) + if((W.z in config.station_levels) && !istype(get_area(W), /area/bridge) && !istype(get_area(W), /area/crew_quarters) && !istype(get_area(W), /area/security/prison)) W.req_access = list() message_admins("[key_name_admin(usr)] activated Egalitarian Station mode") - command_alert("Centcomm airlock control override activated. Please take this time to get acquainted with your coworkers.") - world << sound('sound/AI/commandreport.ogg') + command_announcement.Announce("Centcomm airlock control override activated. Please take this time to get acquainted with your coworkers.", new_sound = 'sound/AI/commandreport.ogg') if("dorf") feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","DF") @@ -2500,8 +2611,7 @@ message_admins("[key_name_admin(usr)] triggered an ion storm") var/show_log = alert(usr, "Show ion message?", "Message", "Yes", "No") if(show_log == "Yes") - command_alert("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert") - world << sound('sound/AI/ionstorm.ogg') + command_announcement.Announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", new_sound = 'sound/AI/ionstorm.ogg') if("carp") feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","Crp") diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 3038b414334..2dd6ed7f892 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -21,7 +21,7 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey"," src.verbs += /client/verb/adminhelp // 2 minute cool-down for adminhelps//Go to hell **/ var/msg - var/list/type = list("Player Complaint","Question","Bug Report","Event") + var/list/type = list("Question","Player Complaint") var/selected_type = input("Pick a category.", "Admin Help", null, null) as null|anything in type if(selected_type) msg = input("Please enter your message.", "Admin Help", null, null) as text @@ -100,11 +100,9 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey"," var/admin_number_afk = 0 var/list/modholders = list() var/list/banholders = list() - var/list/debugholders = list() var/list/adminholders = list() - var/list/eventholders = list() for(var/client/X in admins) - if(R_MOD & X.holder.rights) + if((R_MOD | R_MENTOR) & X.holder.rights) if(X.is_afk()) admin_number_afk++ modholders += X @@ -114,10 +112,6 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey"," adminholders += X if(R_BAN & X.holder.rights) banholders += X - if(R_DEBUG & X.holder.rights) - debugholders += X - if(R_EVENT & X.holder.rights) - eventholders += X switch(selected_type) if("Question") @@ -132,30 +126,6 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey"," if(X.prefs.sound & SOUND_ADMINHELP) X << 'sound/effects/adminhelp.ogg' X << msg - else if("Bug Report") - if(debugholders.len) - for(var/client/X in debugholders) - if(X.prefs.sound & SOUND_ADMINHELP) - X << 'sound/effects/adminhelp.ogg' - X << msg - else - if(adminholders.len) - for(var/client/X in adminholders) - if(X.prefs.sound & SOUND_ADMINHELP) - X << 'sound/effects/adminhelp.ogg' - X << msg - else if("Event") - if(eventholders.len) - for(var/client/X in eventholders) - if(X.prefs.sound & SOUND_ADMINHELP) - X << 'sound/effects/adminhelp.ogg' - X << msg - else - if(banholders.len) - for(var/client/X in banholders) - if(X.prefs.sound & SOUND_ADMINHELP) - X << 'sound/effects/adminhelp.ogg' - X << msg else if("Player Complaint") if(banholders.len) for(var/client/X in banholders) diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index 83f43ba6d9c..0b244992381 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -103,7 +103,7 @@ //mod PMs are maroon //PMs sent from admins and mods display their rank if(holder) - if( holder.rights & R_MOD && !holder.rights & R_ADMIN ) + if( holder.rights & (R_MOD | R_MENTOR) && !holder.rights & R_ADMIN ) recieve_color = "maroon" else recieve_color = "red" @@ -204,20 +204,14 @@ var/list/modholders = list() var/list/banholders = list() - var/list/debugholders = list() var/list/adminholders = list() - var/list/eventholders = list() for(var/client/X in admins) - if(R_MOD & X.holder.rights) + if((R_MOD | R_MENTOR) & X.holder.rights) modholders += X if(R_ADMIN & X.holder.rights) adminholders += X - if(R_DEBUG & X.holder.rights) - debugholders += X if(R_BAN & X.holder.rights) banholders += X - if(R_EVENT & X.holder.rights) - eventholders += X //we don't use message_admins here because the sender/receiver might get it too for(var/client/X in admins) @@ -227,20 +221,10 @@ if(X.key!=key && X.key!=C.key) switch(type) if("Question") - if(X.holder.rights & R_MOD) + if(X.holder.rights & (R_MOD | R_MENTOR)) X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: \blue [msg]" //inform X else if(!modholders.len && X.holder.rights & R_ADMIN) X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: \blue [msg]" //Any admins in backup of mod question - if("Bug Report") - if(X.holder.rights & R_DEBUG) - X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: \blue [msg]" //inform X - else if(!debugholders.len && X.holder.rights & R_ADMIN) - X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: \blue [msg]" //Any admins in backup of bug reports - if("Event") - if(X.holder.rights & R_EVENT) - X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: \blue [msg]" //inform X - else if(!eventholders.len && X.holder.rights & R_BAN) - X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: \blue [msg]" //Quality in backup of Event if("Player Complaint") if(X.holder.rights & R_BAN) X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: \blue [msg]" //There should always be at least 1 person with +BAN on @@ -273,6 +257,6 @@ for(var/client/X in admins) if(X == src) continue - if((X.holder.rights & R_ADMIN) || (X.holder.rights & R_MOD)) + if((X.holder.rights & R_ADMIN) || (X.holder.rights & (R_MOD | R_MENTOR))) X << "PM: [key_name(src, X, 0)]->IRC-Admins: \blue [msg]" diff --git a/code/modules/admin/verbs/adminsay.dm b/code/modules/admin/verbs/adminsay.dm index ceefd17c3a6..209ce6b0b32 100644 --- a/code/modules/admin/verbs/adminsay.dm +++ b/code/modules/admin/verbs/adminsay.dm @@ -2,20 +2,17 @@ set category = "Special Verbs" set name = "Asay" //Gave this shit a shorter name so you only have to time out "asay" rather than "admin say" to use it --NeoFite set hidden = 1 - if(!check_rights(R_ADMIN)) return - msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN) + msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN)) if(!msg) return log_admin("[key_name(src)] : [msg]") - var/color = "admin" + if(check_rights(R_ADMIN,0)) - color = "adminchat" - msg = "ADMIN: [key_name(usr, 1)] (JMP): [msg]" for(var/client/C in admins) if(R_ADMIN & C.holder.rights) - C << msg + C << "ADMIN: [key_name(usr, 1)] (JMP): [msg]" feedback_add_details("admin_verb","M") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -26,18 +23,17 @@ if(!check_rights(R_ADMIN|R_MOD)) return - msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN) + msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN)) log_admin("MOD: [key_name(src)] : [msg]") if (!msg) return - var/color = "mod" - if (check_rights(R_ADMIN,0)) - color = "adminmod" - var/channel = "MOD:" - if(config.mods_are_mentors) - channel = "MENTOR:" + var/spanclass = "mod_channel" + if(check_rights(R_ADMIN, 0)) + spanclass = "mod_channel_admin" for(var/client/C in admins) - if((R_ADMIN|R_MOD) & C.holder.rights) - C << "[channel] [key_name(src,1)] (JMP): [msg]" + if(R_MOD & C.holder.rights) + C << "MOD: [key_name(usr, 1)] (JMP): [msg]" + + feedback_add_details("admin_verb","MS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! \ No newline at end of file diff --git a/code/modules/admin/verbs/deadsay.dm b/code/modules/admin/verbs/deadsay.dm index b4253848893..1a4da3d8c58 100644 --- a/code/modules/admin/verbs/deadsay.dm +++ b/code/modules/admin/verbs/deadsay.dm @@ -18,32 +18,23 @@ if (src.handle_spam_prevention(msg,MUTE_DEADCHAT)) return - var/stafftype = null - if(src.holder.rights & R_MOD && !(src.holder.rights & R_ADMIN)) - stafftype = "MENTOR" + if (src.holder.rights & R_MOD) + stafftype = "MOD" + if (src.holder.rights & R_MENTOR) + stafftype = "MENTOR" if (src.holder.rights & R_ADMIN) stafftype = "ADMIN" - msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN) + msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN)) log_admin("[key_name(src)] : [msg]") if (!msg) return - var/rendered = "DEAD: [stafftype] says, \"[msg]\"" - - for (var/mob/M in player_list) - if (istype(M, /mob/new_player)) - continue - - if(M.client && M.client.holder && (M.client.prefs.toggles & CHAT_DEAD)) // show the message to admins who have deadchat toggled on - M.show_message(rendered, 2) - - else if(M.stat == DEAD && (M.client.prefs.toggles & CHAT_DEAD)) // show the message to regular ghosts who have deadchat toggled on - M.show_message(rendered, 2) + say_dead_direct("[stafftype] ([src.holder.fakekey ? src.holder.fakekey : src.key]) says, \"[msg]\"") feedback_add_details("admin_verb","D") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index abd1f40f15a..8bd0f7c4c47 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -899,7 +899,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that M.equip_if_possible(pda, slot_r_store) M.equip_if_possible(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store) - M.equip_if_possible(new /obj/item/weapon/gun/energy/pulse_rifle/M1911(M), slot_belt) + M.equip_if_possible(new /obj/item/weapon/gun/energy/pulse_rifle/pistol/m1911(M), slot_belt) var/obj/item/weapon/card/id/centcom/W = new(M) W.name = "[M.real_name]'s ID Card (Nanotrasen Navy Captain)" @@ -964,7 +964,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/eyepatch(M), slot_glasses) M.equip_to_slot_or_del(new /obj/item/clothing/mask/cigarette/cigar/cohiba(M), slot_wear_mask) M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/deathsquad/beret(M), slot_head) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle/M1911(M), slot_belt) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle/pistol/m1911(M), slot_belt) M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/matches(M), slot_r_store) M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back) @@ -992,7 +992,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that M.equip_if_possible(new /obj/item/clothing/gloves/color/white(M), slot_gloves) M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes) M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/deathsquad/beret(M), slot_head) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle/M1911(M), slot_belt) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle/pistol/m1911(M), slot_belt) M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back) var/obj/item/device/pda/centcom/pda = new(M) @@ -1025,7 +1025,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that M.equip_to_slot_or_del(new /obj/item/clothing/glasses/meson/cyber(M), slot_glasses) M.equip_to_slot_or_del(new /obj/item/clothing/mask/breath(M), slot_wear_mask) M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/singuloth(M), slot_head) - M.equip_to_slot_or_del(new /obj/item/weapon/claymore(M), slot_belt) + M.equip_to_slot_or_del(new /obj/item/weapon/claymore/ceremonial(M), slot_belt) M.equip_to_slot_or_del(new /obj/item/weapon/tank/oxygen(M), slot_s_store) M.equip_to_slot_or_del(new /obj/item/weapon/twohanded/knighthammer(M), slot_back) @@ -1104,7 +1104,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/cyber(M), slot_glasses) M.equip_to_slot_or_del(new /obj/item/clothing/mask/cigarette/cigar/cohiba(M), slot_wear_mask) M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/deathsquad/beret(M), slot_head) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle/M1911(M), slot_belt) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle/pistol/m1911(M), slot_belt) M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/matches(M), slot_r_store) M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back) @@ -1130,7 +1130,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that M.equip_if_possible(new /obj/item/clothing/gloves/color/white(M), slot_gloves) M.equip_to_slot_or_del(new /obj/item/clothing/shoes/centcom(M), slot_shoes) M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/deathsquad/beret(M), slot_head) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle/M1911(M), slot_belt) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle/pistol/m1911(M), slot_belt) M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back) M.equip_to_slot_or_del(new /obj/item/clothing/mask/cigarette/cigar/cohiba(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/matches(M), slot_in_backpack) diff --git a/code/modules/admin/verbs/freeze.dm b/code/modules/admin/verbs/freeze.dm new file mode 100644 index 00000000000..502060933ee --- /dev/null +++ b/code/modules/admin/verbs/freeze.dm @@ -0,0 +1,125 @@ +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////Freeze Mob/Mech Verb -- Ported from NSS Pheonix (Unbound Travels)///////// +//////////////////////////////////////////////////////////////////////////////// +//////Allows admin's to right click on any mob/mech and freeze them in place./// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +/client/proc/freeze(mob/living/M as mob in mob_list) + set category = "Special Verbs" + set name = "Freeze" + if(!holder) + src << "Only administrators may use this command." + return + if(!mob) + return + if(!istype(M)) + alert("Cannot freeze a ghost") + return + if(usr) + if (usr.client) + if(usr.client.holder) + if (istype(M, /mob/living/carbon/slime)) + if(!M.paralysis) + M.adjustToxLoss(2147483647) + M.AdjustParalysis(2147483647) + var/adminomaly = new/obj/effect/overlay/adminoverlay + spawn(50) + M.overlays += adminomaly + M << "You have been frozen by [key]" + message_admins("\blue [key_name_admin(usr)] froze [key_name(M)]") + log_admin("[key_name(usr)] froze [key_name(M)]") + else if (M.paralysis) + M.AdjustParalysis(-2147483647) + M.blinded = 0 + M.lying = 0 + M.stat = 0 + M << " You have been unfrozen by [key]" + message_admins("\blue [key_name_admin(usr)] unfroze [key_name(M)]") + log_admin("[key_name(usr)] unfroze [key_name(M)]") + M.revive() + else if (istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/FM = M + + if(!FM.paralysis) + FM.anchored = 1 + FM.frozen = 1 + FM.AdjustParalysis(2147483647) + var/adminomaly = new/obj/effect/overlay/adminoverlay + spawn(50) + FM.overlays += adminomaly + FM << "You have been frozen by [key]" + message_admins("\blue [key_name_admin(usr)] froze [key_name(FM)]") + log_admin("[key_name(usr)] froze [key_name(FM)]") + else if (M.paralysis) + FM.anchored = 0 + FM.frozen = 0 + FM.AdjustParalysis(-2147483647) + FM.blinded = 0 + FM.lying = 0 + FM.stat = 0 + + FM << " You have been unfrozen by [key]" + message_admins("\blue [key_name_admin(usr)] unfroze [key_name(FM)]") + log_admin("[key_name(usr)] unfroze [key_name(FM)]") + + else + + if(!M.paralysis) + M.anchored = 1 + M.AdjustParalysis(2147483647) + var/adminomaly = new/obj/effect/overlay/adminoverlay + spawn(50) + M.overlays += adminomaly + M << "You have been frozen by [key]" + message_admins("\blue [key_name_admin(usr)] froze [key_name(M)]") + log_admin("[key_name(usr)] froze [key_name(M)]") + else if (M.paralysis) + M.anchored = 0 + M.AdjustParalysis(-2147483647) + M.blinded = 0 + M.lying = 0 + M.stat = 0 + + M << " You have been unfrozen by [key]" + message_admins("\blue [key_name_admin(usr)] unfroze [key_name(M)]") + log_admin("[key_name(usr)] unfroze [key_name(M)]") + + +/client/proc/freezemecha(obj/mecha/O as obj in mechas_list) + set category = "Special Verbs" + set name = "Freeze Mech" + if(!holder) + src << "Only administrators may use this command." + return + var/obj/mecha/M = O + if(!istype(M,/obj/mecha)) + src << "\red This can only be used on Mechs!" + return + else + if(usr) + if (usr.client) + if(usr.client.holder) + var/adminomaly = new/obj/effect/overlay/adminoverlay + if(M.can_move == 1) + M.can_move = 0 + M.overlays += adminomaly + if(M.occupant) + M.removeVerb(/obj/mecha/verb/eject) + M.occupant << "You have been frozen by [key]" + message_admins("\blue [key_name_admin(usr)] froze [key_name(M.occupant)] in a [M.name]") + log_admin("[key_name(usr)] froze [key_name(M.occupant)] in a [M.name]") + else + message_admins("\blue [key_name_admin(usr)] froze an empty [M.name]") + log_admin("[key_name(usr)] froze an empty [M.name]") + else if(M.can_move == 0) + M.can_move = 1 + M.overlays -= adminomaly + if(M.occupant) + M.addVerb(/obj/mecha/verb/eject) + M.occupant << "You have been unfrozen by [key]" + message_admins("\blue [key_name_admin(usr)] unfroze [key_name(M.occupant)] in a [M.name]") + log_admin("[key_name(usr)] unfroze [M.occupant.name]/[M.occupant.ckey] in a [M.name]") + else + message_admins("\blue [key_name_admin(usr)] unfroze an empty [M.name]") + log_admin("[key_name(usr)] unfroze an empty [M.name]") diff --git a/code/modules/admin/verbs/honksquad.dm b/code/modules/admin/verbs/honksquad.dm index beb903bf5b0..5583b36435b 100644 --- a/code/modules/admin/verbs/honksquad.dm +++ b/code/modules/admin/verbs/honksquad.dm @@ -19,7 +19,7 @@ var/global/sent_honksquad = 0 var/input = null while(!input) - input = copytext(sanitize(input(src, "Please specify which mission the HONKsquad shall undertake.", "Specify Mission", "")),1,MAX_MESSAGE_LEN) + input = sanitize(copytext(input(src, "Please specify which mission the HONKsquad shall undertake.", "Specify Mission", ""),1,MAX_MESSAGE_LEN)) if(!input) if(alert("Error, no mission set. Do you want to exit the setup process?",,"Yes","No")=="Yes") return @@ -119,7 +119,7 @@ var/global/sent_honksquad = 0 equip_to_slot_or_del(new /obj/item/toy/crayon/rainbow(src), slot_in_backpack) equip_to_slot_or_del(new /obj/item/weapon/gun/energy/clown(src), slot_in_backpack) equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/spray/waterflower(src), slot_in_backpack) - src.mutations.Add(M_CLUMSY) + src.mutations.Add(CLUMSY) diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index 1aeed58f7df..c250ceca9d0 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -52,7 +52,7 @@ var/intercom_range_display_status = 0 del(C) if(camera_range_display_status) - for(var/obj/machinery/camera/C in cameranet.viewpoints) + for(var/obj/machinery/camera/C in cameranet.cameras) new/obj/effect/debugging/camera_range(C.loc) feedback_add_details("admin_verb","mCRD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -68,7 +68,7 @@ var/intercom_range_display_status = 0 var/list/obj/machinery/camera/CL = list() - for(var/obj/machinery/camera/C in cameranet.viewpoints) + for(var/obj/machinery/camera/C in cameranet.cameras) CL += C var/output = {"CAMERA ANOMALIES REPORT
    diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 4ae2a560421..954c0618e16 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -14,23 +14,14 @@ client/proc/one_click_antag() var/dat = {"One-click Antagonist
    Make Traitors
    - Make Changlings
    - Make Revs
    + Make Changelings
    + Make Revolutionaries
    Make Cult
    Make Malf AI
    Make Wizard (Requires Ghosts)
    - Make Vox Raiders (Requires Ghosts)
    + Make Vampires
    + Make Vox Raiders (Requires Ghosts)
    "} -/* These dont work just yet - Ninja, aliens and deathsquad I have not looked into yet - Nuke team is getting a null mob returned from makebody() (runtime error: null.mind. Line 272) - - Make Nuke Team (Requires Ghosts)
    - Make Space Ninja (Requires Ghosts)
    - Make Aliens (Requires Ghosts)
    - Make Deathsquad (Syndicate) (Requires Ghosts)
    - "} -*/ usr << browse(dat, "window=oneclickantag;size=400x400") return @@ -42,7 +33,7 @@ client/proc/one_click_antag() var/datum/mind/themind = null for(var/mob/living/silicon/ai/ai in player_list) - if(ai.client) + if(ai.client && ai.client.prefs.be_special & BE_MALF) AIs += ai if(AIs.len) @@ -67,12 +58,14 @@ client/proc/one_click_antag() for(var/mob/living/carbon/human/applicant in player_list) if(applicant.client.prefs.be_special & BE_TRAITOR) - if(!applicant.stat) - if(applicant.mind) - if (!applicant.mind.special_role) - if(!jobban_isbanned(applicant, "traitor") && !jobban_isbanned(applicant, "Syndicate")) - if(!(applicant.job in temp.restricted_jobs)) - candidates += applicant + if(player_old_enough_antag(applicant.client,BE_TRAITOR)) + if(!applicant.stat) + if(applicant.mind) + if (!applicant.mind.special_role) + if(!jobban_isbanned(applicant, "traitor") && !jobban_isbanned(applicant, "Syndicate")) + if(!(applicant.mind.assigned_role in temp.restricted_jobs)) + if(!(applicant.client.prefs.species in temp.protected_species)) + candidates += applicant if(candidates.len) var/numTratiors = min(candidates.len, 3) @@ -99,12 +92,14 @@ client/proc/one_click_antag() for(var/mob/living/carbon/human/applicant in player_list) if(applicant.client.prefs.be_special & BE_CHANGELING) - if(!applicant.stat) - if(applicant.mind) - if (!applicant.mind.special_role) - if(!jobban_isbanned(applicant, "changeling") && !jobban_isbanned(applicant, "Syndicate")) - if(!(applicant.job in temp.restricted_jobs)) - candidates += applicant + if(player_old_enough_antag(applicant.client,BE_CHANGELING)) + if(!applicant.stat) + if(applicant.mind) + if (!applicant.mind.special_role) + if(!jobban_isbanned(applicant, "changeling") && !jobban_isbanned(applicant, "Syndicate")) + if(!(applicant.mind.assigned_role in temp.restricted_jobs)) + if(!(applicant.client.prefs.species in temp.protected_species)) + candidates += applicant if(candidates.len) var/numChanglings = min(candidates.len, 3) @@ -129,12 +124,14 @@ client/proc/one_click_antag() for(var/mob/living/carbon/human/applicant in player_list) if(applicant.client.prefs.be_special & BE_REV) - if(applicant.stat == CONSCIOUS) - if(applicant.mind) - if(!applicant.mind.special_role) - if(!jobban_isbanned(applicant, "revolutionary") && !jobban_isbanned(applicant, "Syndicate")) - if(!(applicant.job in temp.restricted_jobs)) - candidates += applicant + if(player_old_enough_antag(applicant.client,BE_REV)) + if(applicant.stat == CONSCIOUS) + if(applicant.mind) + if(!applicant.mind.special_role) + if(!jobban_isbanned(applicant, "revolutionary") && !jobban_isbanned(applicant, "Syndicate")) + if(!(applicant.mind.assigned_role in temp.restricted_jobs)) + if(!(applicant.client.prefs.species in temp.protected_species)) + candidates += applicant if(candidates.len) var/numRevs = min(candidates.len, 3) @@ -153,17 +150,19 @@ client/proc/one_click_antag() var/time_passed = world.time for(var/mob/G in respawnable_list) - if(!jobban_isbanned(G, "wizard") && !jobban_isbanned(G, "Syndicate")) - spawn(0) - switch(G.timed_alert("Do you wish to be considered for the position of Space Wizard Foundation 'diplomat'?","Please answer in 30 seconds!","No",300,"Yes","No"))//alert(G, "Do you wish to be considered for the position of Space Wizard Foundation 'diplomat'?","Please answer in 30 seconds!","Yes","No")) - if("Yes") - if((world.time-time_passed)>300)//If more than 30 game seconds passed. - return - candidates += G - if("No") - return - else - return + if(G.client.prefs.be_special & BE_WIZARD) + if(!jobban_isbanned(G, "wizard") && !jobban_isbanned(G, "Syndicate")) + if(player_old_enough_antag(G.client,BE_WIZARD)) + spawn(0) + switch(G.timed_alert("Do you wish to be considered for the position of Space Wizard Foundation 'diplomat'?","Please answer in 30 seconds!","No",300,"Yes","No"))//alert(G, "Do you wish to be considered for the position of Space Wizard Foundation 'diplomat'?","Please answer in 30 seconds!","Yes","No")) + if("Yes") + if((world.time-time_passed)>300)//If more than 30 game seconds passed. + return + candidates += G + if("No") + return + else + return sleep(300) @@ -194,12 +193,14 @@ client/proc/one_click_antag() for(var/mob/living/carbon/human/applicant in player_list) if(applicant.client.prefs.be_special & BE_CULTIST) - if(applicant.stat == CONSCIOUS) - if(applicant.mind) - if(!applicant.mind.special_role) - if(!jobban_isbanned(applicant, "cultist") && !jobban_isbanned(applicant, "Syndicate")) - if(!(applicant.job in temp.restricted_jobs)) - candidates += applicant + if(player_old_enough_antag(applicant.client,BE_CULTIST)) + if(applicant.stat == CONSCIOUS) + if(applicant.mind) + if(!applicant.mind.special_role) + if(!jobban_isbanned(applicant, "cultist") && !jobban_isbanned(applicant, "Syndicate")) + if(!(applicant.mind.assigned_role in temp.restricted_jobs)) + if(!(applicant.client.prefs.species in temp.protected_species)) + candidates += applicant if(candidates.len) var/numCultists = min(candidates.len, 4) @@ -223,17 +224,19 @@ client/proc/one_click_antag() var/time_passed = world.time for(var/mob/G in respawnable_list) - if(!jobban_isbanned(G, "operative") && !jobban_isbanned(G, "Syndicate")) - spawn(0) - switch(alert(G,"Do you wish to be considered for a nuke team being sent in?","Please answer in 30 seconds!","Yes","No")) - if("Yes") - if((world.time-time_passed)>300)//If more than 30 game seconds passed. - return - candidates += G - if("No") - return - else - return + if(G.client.prefs.be_special & BE_OPERATIVE) + if(!jobban_isbanned(G, "operative") && !jobban_isbanned(G, "Syndicate")) + if(player_old_enough_antag(G.client,BE_OPERATIVE)) + spawn(0) + switch(alert(G,"Do you wish to be considered for a nuke team being sent in?","Please answer in 30 seconds!","Yes","No")) + if("Yes") + if((world.time-time_passed)>300)//If more than 30 game seconds passed. + return + candidates += G + if("No") + return + else + return sleep(300) @@ -328,16 +331,17 @@ client/proc/one_click_antag() //Generates a list of commandos from active ghosts. Then the user picks which characters to respawn as the commandos. for(var/mob/G in respawnable_list) - spawn(0) - switch(alert(G,"Do you wish to be considered for an elite syndicate strike team being sent in?","Please answer in 30 seconds!","Yes","No")) - if("Yes") - if((world.time-time_passed)>300)//If more than 30 game seconds passed. + if(!jobban_isbanned(G, "Syndicate")) + spawn(0) + switch(alert(G,"Do you wish to be considered for an elite syndicate strike team being sent in?","Please answer in 30 seconds!","Yes","No")) + if("Yes") + if((world.time-time_passed)>300)//If more than 30 game seconds passed. + return + candidates += G + if("No") + return + else return - candidates += G - if("No") - return - else - return sleep(300) for(var/mob/dead/observer/G in candidates) @@ -445,16 +449,19 @@ client/proc/one_click_antag() //Generates a list of candidates from active ghosts. for(var/mob/G in respawnable_list) - spawn(0) - switch(alert(G,"Do you wish to be considered for a vox raiding party arriving on the station?","Please answer in 30 seconds!","Yes","No")) - if("Yes") - if((world.time-time_passed)>300)//If more than 30 game seconds passed. - return - candidates += G - if("No") - return - else - return + if(G.client.prefs.be_special & BE_RAIDER) + if(player_old_enough_antag(G.client,BE_RAIDER)) + if(!jobban_isbanned(G, "raider") && !jobban_isbanned(G, "Syndicate")) + spawn(0) + switch(alert(G,"Do you wish to be considered for a vox raiding party arriving on the station?","Please answer in 30 seconds!","Yes","No")) + if("Yes") + if((world.time-time_passed)>300)//If more than 30 game seconds passed. + return + candidates += G + if("No") + return + else + return sleep(300) //Debug. @@ -532,4 +539,36 @@ client/proc/one_click_antag() ticker.mode.traitors += new_vox.mind new_vox.equip_vox_raider() - return new_vox \ No newline at end of file + return new_vox + +/datum/admins/proc/makeVampires() + + var/datum/game_mode/vampire/temp = new + if(config.protect_roles_from_antagonist) + temp.restricted_jobs += temp.protected_jobs + + var/list/mob/living/carbon/human/candidates = list() + var/mob/living/carbon/human/H = null + + for(var/mob/living/carbon/human/applicant in player_list) + if(applicant.client.prefs.be_special & BE_VAMPIRE) + if(player_old_enough_antag(applicant.client,BE_VAMPIRE)) + if(!applicant.stat) + if(applicant.mind) + if (!applicant.mind.special_role) + if(!jobban_isbanned(applicant, "vampire") && !jobban_isbanned(applicant, "Syndicate")) + if(!(applicant.job in temp.restricted_jobs)) + if(!(applicant.client.prefs.species in temp.protected_species)) + candidates += applicant + + if(candidates.len) + var/numVampires = min(candidates.len, 3) + + for(var/i = 0, iA pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited.
    " else status = 0 diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index c8a2b81facd..127f3c5d9ca 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -3,7 +3,7 @@ icon = 'icons/obj/assemblies/new_assemblies.dmi' icon_state = "holder" item_state = "assembly" - flags = FPRINT | CONDUCT + flags = CONDUCT throwforce = 5 w_class = 2.0 throw_speed = 3 @@ -130,7 +130,7 @@ return - attackby(obj/item/weapon/W as obj, mob/user as mob) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/screwdriver)) if(!a_left || !a_right) user << "\red BUG:Assembly part missing, please report this!" diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index a7ac697ad8f..507f879cca4 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -19,7 +19,7 @@ if(!armed) if(ishuman(usr)) var/mob/living/carbon/human/user = usr - if(((user.getBrainLoss() >= 60 || (M_CLUMSY in user.mutations)) && prob(50))) + if(((user.getBrainLoss() >= 60 || (CLUMSY in user.mutations)) && prob(50))) user << "Your hand slips, setting off the trigger." pulse(0) update_icon() @@ -69,7 +69,7 @@ if(!armed) user << "You arm [src]." else - if(((user.getBrainLoss() >= 60 || (M_CLUMSY in user.mutations)) && prob(50))) + if(((user.getBrainLoss() >= 60 || (CLUMSY in user.mutations)) && prob(50))) var/which_hand = "l_hand" if(!user.hand) which_hand = "r_hand" @@ -85,7 +85,7 @@ attack_hand(mob/living/user as mob) if(armed) - if(((user.getBrainLoss() >= 60 || M_CLUMSY in user.mutations)) && prob(50)) + if(((user.getBrainLoss() >= 60 || CLUMSY in user.mutations)) && prob(50)) var/which_hand = "l_hand" if(!user.hand) which_hand = "r_hand" diff --git a/code/modules/assembly/shock_kit.dm b/code/modules/assembly/shock_kit.dm index 6b34017704c..53bbd47beca 100644 --- a/code/modules/assembly/shock_kit.dm +++ b/code/modules/assembly/shock_kit.dm @@ -7,7 +7,7 @@ var/obj/item/device/radio/electropack/part2 = null var/status = 0 w_class = 5.0 - flags = FPRINT | CONDUCT + flags = CONDUCT /obj/item/assembly/shock_kit/Destroy() del(part1) @@ -15,7 +15,7 @@ ..() return -/obj/item/assembly/shock_kit/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/assembly/shock_kit/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/wrench) && !status) var/turf/T = loc if(ismob(T)) diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index 7f2d7c8f731..a46b683ca45 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -3,8 +3,8 @@ desc = "Used to remotely activate devices." icon_state = "signaller" item_state = "signaler" - m_amt = 1000 - g_amt = 200 + m_amt = 400 + g_amt = 120 origin_tech = "magnets=1" wires = WIRE_RECEIVE | WIRE_PULSE | WIRE_RADIO_PULSE | WIRE_RADIO_RECEIVE @@ -144,14 +144,13 @@ proc/set_frequency(new_frequency) - if(!radio_controller) - sleep(20) - if(!radio_controller) + spawn(20) + if(!radio_controller) + return + radio_controller.remove_object(src, frequency) + frequency = new_frequency + radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT) return - radio_controller.remove_object(src, frequency) - frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT) - return // Embedded signaller used in anomalies. /obj/item/device/assembly/signaler/anomaly diff --git a/code/modules/awaymissions/bluespaceartillery.dm b/code/modules/awaymissions/bluespaceartillery.dm index 06dfa6b5bcf..03509d38ac3 100644 --- a/code/modules/awaymissions/bluespaceartillery.dm +++ b/code/modules/awaymissions/bluespaceartillery.dm @@ -42,7 +42,7 @@ if (usr.stat || usr.restrained()) return if(src.reload < 180) return if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) - command_alert("Bluespace artillery fire detected. Brace for impact.") + command_announcement.Announce("Bluespace artillery fire detected. Brace for impact.") message_admins("[key_name_admin(usr)] has launched an artillery strike.", 1) var/list/L = list() for(var/turf/T in get_area_turfs(thearea.type)) @@ -55,7 +55,7 @@ var/A A = input("Area to jump bombard", "Open Fire", A) in teleportlocs var/area/thearea = teleportlocs[A] - command_alert("Bluespace artillery fire detected. Brace for impact.") + command_announcement.Announce("Bluespace artillery fire detected. Brace for impact.") spawn(30) var/list/L = list() diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index f62cef10073..7fa81ce358e 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -35,7 +35,6 @@ /obj/effect/landmark/corpse/proc/createCorpse() //Creates a mob and checks for gear in each slot before attempting to equip it. var/mob/living/carbon/human/human/M = new /mob/living/carbon/human/human (src.loc) - M.dna.mutantrace = mutantrace M.real_name = src.name M.death(1) //Kills the new mob M.timeofdeath = timeofdeath diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm index 859242947a9..ca47ab1afc7 100644 --- a/code/modules/awaymissions/gateway.dm +++ b/code/modules/awaymissions/gateway.dm @@ -137,7 +137,7 @@ obj/machinery/gateway/centerstation/process() return -/obj/machinery/gateway/centerstation/attackby(obj/item/device/W as obj, mob/user as mob) +/obj/machinery/gateway/centerstation/attackby(obj/item/device/W as obj, mob/user as mob, params) if(istype(W,/obj/item/device/multitool)) user << "\black The gate is already calibrated, there is no work for you to do here." return @@ -234,7 +234,7 @@ obj/machinery/gateway/centerstation/process() M.dir = SOUTH -/obj/machinery/gateway/centeraway/attackby(obj/item/device/W as obj, mob/user as mob) +/obj/machinery/gateway/centeraway/attackby(obj/item/device/W as obj, mob/user as mob, params) if(istype(W,/obj/item/device/multitool)) if(calibrated) user << "\black The gate is already calibrated, there is no work for you to do here." diff --git a/code/modules/awaymissions/mission_code/academy.dm b/code/modules/awaymissions/mission_code/academy.dm index 997276e74b8..16af3141647 100644 --- a/code/modules/awaymissions/mission_code/academy.dm +++ b/code/modules/awaymissions/mission_code/academy.dm @@ -3,6 +3,7 @@ /area/awaymission/academy name = "\improper Academy Asteroids" icon_state = "away" + report_alerts = 0 /area/awaymission/academy/headmaster name = "\improper Academy Fore Block" diff --git a/code/modules/awaymissions/mission_code/blackmarketpackers.dm b/code/modules/awaymissions/mission_code/blackmarketpackers.dm index d2d215053af..468863f3026 100644 --- a/code/modules/awaymissions/mission_code/blackmarketpackers.dm +++ b/code/modules/awaymissions/mission_code/blackmarketpackers.dm @@ -4,7 +4,7 @@ name = "\improper BMP Asteroids" icon_state = "away" luminosity = 0 - + report_alerts = 0 /area/awaymission/BMPship/Aft name = "\improper Aft Block" diff --git a/code/modules/awaymissions/mission_code/centcomAway.dm b/code/modules/awaymissions/mission_code/centcomAway.dm index 70be2fa7202..06f36c5bf44 100644 --- a/code/modules/awaymissions/mission_code/centcomAway.dm +++ b/code/modules/awaymissions/mission_code/centcomAway.dm @@ -4,7 +4,8 @@ name = "XCC-P5831" icon_state = "away" requires_power = 0 - + report_alerts = 0 + /area/awaymission/centcomAway/general name = "XCC-P5831" music = "music/ambigen3.ogg" diff --git a/code/modules/awaymissions/mission_code/challenge.dm b/code/modules/awaymissions/mission_code/challenge.dm index f7aa861eb80..966ce6053f6 100644 --- a/code/modules/awaymissions/mission_code/challenge.dm +++ b/code/modules/awaymissions/mission_code/challenge.dm @@ -1,5 +1,10 @@ //Challenge Areas +/area/awaymission/challenge + name = "Challenge" + icon_state = "away" + report_alerts = 0 + /area/awaymission/challenge/start name = "Where Am I?" icon_state = "away" diff --git a/code/modules/awaymissions/mission_code/clownplanet.dm b/code/modules/awaymissions/mission_code/clownplanet.dm index 45b0dc1c7de..359037ada0a 100644 --- a/code/modules/awaymissions/mission_code/clownplanet.dm +++ b/code/modules/awaymissions/mission_code/clownplanet.dm @@ -6,6 +6,7 @@ luminosity = 1 lighting_use_dynamic = 0 requires_power = 0 + report_alerts = 0 /area/awaymission/clownplanet/miningtown name = "\improper Clown Planet - Bananium-o-Rama" diff --git a/code/modules/awaymissions/mission_code/spacebattle.dm b/code/modules/awaymissions/mission_code/spacebattle.dm index dc86365f4ee..3f9c9925772 100644 --- a/code/modules/awaymissions/mission_code/spacebattle.dm +++ b/code/modules/awaymissions/mission_code/spacebattle.dm @@ -4,6 +4,7 @@ name = "\improper Space Battle" icon_state = "away" requires_power = 0 + report_alerts = 0 /area/awaymission/spacebattle/cruiser name = "\improper Nanotrasen Cruiser" diff --git a/code/modules/awaymissions/mission_code/stationCollision.dm b/code/modules/awaymissions/mission_code/stationCollision.dm index fdfd016e40a..dee5ae20af6 100644 --- a/code/modules/awaymissions/mission_code/stationCollision.dm +++ b/code/modules/awaymissions/mission_code/stationCollision.dm @@ -19,6 +19,9 @@ * Areas */ //Gateroom gets its own APC specifically for the gate + /area/awaymission + report_alerts = 0 + /area/awaymission/gateroom //Library, medbay, storage room diff --git a/code/modules/awaymissions/mission_code/wildwest.dm b/code/modules/awaymissions/mission_code/wildwest.dm index 3a91028f2df..180fbf7a331 100644 --- a/code/modules/awaymissions/mission_code/wildwest.dm +++ b/code/modules/awaymissions/mission_code/wildwest.dm @@ -77,9 +77,9 @@ if("Power") user << "Your wish is granted, but at a terrible cost..." user << "The Wish Granter punishes you for your selfishness, claiming your soul and warping your body to match the darkness in your heart." - user.mutations.Add(M_LASER) - user.mutations.Add(M_RESIST_COLD) - user.mutations.Add(M_XRAY) + user.mutations.Add(LASER) + user.mutations.Add(RESIST_COLD) + user.mutations.Add(XRAY) user.dna.mutantrace = "shadow" user.regenerate_icons() if("Wealth") diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 12601237d79..109a257ac03 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -2,38 +2,38 @@ var/list/preferences_datums = list() -var/global/list/special_roles = list( //keep synced with the defines BE_* in setup.dm +var/global/list/special_roles = list( //keep synced with the defines BE_* in setup.dm. THE ORDER MATTERS //some autodetection here. - "pAI" = 1, // 0 - "traitor" = IS_MODE_COMPILED("traitor"), // 1 - "changeling" = IS_MODE_COMPILED("changeling"), // 2 - "vampire" = IS_MODE_COMPILED("vampire"), // 3 - "revolutionary" = IS_MODE_COMPILED("revolution"), // 4 - "blob" = IS_MODE_COMPILED("blob"), // 5 - "operative" = IS_MODE_COMPILED("nuclear"), // 6 - "cultist" = IS_MODE_COMPILED("cult"), // 7 - "wizard" = IS_MODE_COMPILED("wizard"), // 8 - "raider" = IS_MODE_COMPILED("heist"), // 9 - "alien" = 1, // 10 - "ninja" = 1, // 11 - "mutineer" = IS_MODE_COMPILED("mutiny"), // 12 - "malf AI" = IS_MODE_COMPILED("malfunction") // 13 + "traitor" = IS_MODE_COMPILED("traitor"), // 1 / 1 + "operative" = IS_MODE_COMPILED("nuclear"), // 2 / 2 + "changeling" = IS_MODE_COMPILED("changeling"), // 4 / 3 + "wizard" = IS_MODE_COMPILED("wizard"), // 8 / 4 + "malf AI" = IS_MODE_COMPILED("malfunction"), // 16 / 5 + "revolutionary" = IS_MODE_COMPILED("revolution"), // 32 / 6 + "alien" = 1, // 62 / 7 + "pAI" = 1, // 128 / 8 + "cultist" = IS_MODE_COMPILED("cult"), // 256 / 9 + "ninja" = 1, // 512 / 10 + "raider" = IS_MODE_COMPILED("heist"), // 1024 / 11 + "vampire" = IS_MODE_COMPILED("vampire"), // 2048 / 12 + "mutineer" = IS_MODE_COMPILED("mutiny"), // 4096 / 13 + "blob" = IS_MODE_COMPILED("blob") // 8192 / 14 ) var/global/list/special_role_times = list( //minimum age (in days) for accounts to play these roles - num2text(BE_TRAITOR) = 14, - num2text(BE_OPERATIVE) = 21, + num2text(BE_PAI) = 0, + num2text(BE_TRAITOR) = 7, num2text(BE_CHANGELING) = 14, - num2text(BE_WIZARD) = 21, - num2text(BE_MALF) = 30, + num2text(BE_WIZARD) = 14, num2text(BE_REV) = 14, - num2text(BE_ALIEN) = 21, - num2text(BE_PAI) = 0, - num2text(BE_CULTIST) = 21, - num2text(BE_NINJA) = 21, - num2text(BE_RAIDER) = 21, num2text(BE_VAMPIRE) = 14, + num2text(BE_BLOB) = 14, + num2text(BE_OPERATIVE) = 21, + num2text(BE_CULTIST) = 21, + num2text(BE_RAIDER) = 21, + num2text(BE_ALIEN) = 21, + num2text(BE_NINJA) = 21, num2text(BE_MUTINEER) = 21, - num2text(BE_BLOB) = 14 + num2text(BE_MALF) = 30 ) /proc/player_old_enough_antag(client/C, role) @@ -55,6 +55,13 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts return 0 return max(0, minimal_player_age_antag - C.player_age) + +/proc/check_client_age(client/C, var/days) // If days isn't provided, returns the age of the client. If it is provided, it returns the days until the player_age is equal to or greater than the days variable + if(!days) + return C.player_age + else + return max(0, days - C.player_age) + return 0 var/const/MAX_SAVE_SLOTS = 10 @@ -221,7 +228,7 @@ datum/preferences dat += "
    " dat += "Species: [species]
    " if(species == "Vox")//oldvox code, sucks I know - dat += "Old vox? [speciesprefs ? "Yes(Big N2 tank)" : "No(Vox-special N2 tank)"]
    " + dat += "Old Vox? [speciesprefs ? "Yes (Large N2 tank)" : "No(Vox-special N2 tank)"]
    " dat += "Secondary Language:
    [language]
    " dat += "Blood Type: [b_type]
    " if(species == "Human") @@ -327,7 +334,10 @@ datum/preferences dat += "[copytext(flavor_text, 1, 37)]...
    " dat += "
    " - dat += "
    Hair
    " + var/hairname = "Hair" + if(species == "Machine") + hairname = "Frame Color" + dat += "
    [hairname]
    " dat += "Change Color
    __
    " dat += " Style: [h_style]
    " @@ -490,6 +500,8 @@ datum/preferences HTML += " \[Yes]" else HTML += " \[No]" + if(job.alt_titles) + HTML += "
    \[[GetPlayerAltTitle(job)]\]" HTML += "" continue /* @@ -1100,8 +1112,11 @@ datum/preferences b_type = new_b_type if("hair") - if(species == "Human" || species == "Unathi" || species == "Tajaran" || species == "Skrell") - var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference") as color|null + if(species == "Human" || species == "Unathi" || species == "Tajaran" || species == "Skrell" || species == "Machine") + var/input = "Choose your character's hair colour:" + if(species == "Machine") + input = "Choose your character's frame colour:" + var/new_hair = input(user, input, "Character Preference") as color|null if(new_hair) r_hair = hex2num(copytext(new_hair, 2, 4)) g_hair = hex2num(copytext(new_hair, 4, 6)) @@ -1464,8 +1479,8 @@ datum/preferences else continue if(disabilities & DISABILITY_FLAG_FAT && character.species.flags & CAN_BE_FAT)//character.species.flags & CAN_BE_FAT) - character.mutations += M_FAT - character.mutations += M_OBESITY + character.mutations += FAT + character.mutations += OBESITY if(disabilities & DISABILITY_FLAG_NEARSIGHTED) character.disabilities|=NEARSIGHTED if(disabilities & DISABILITY_FLAG_EPILEPTIC) diff --git a/code/modules/client/preferences_mysql.dm b/code/modules/client/preferences_mysql.dm index c4f86593d10..d50d5725bd2 100644 --- a/code/modules/client/preferences_mysql.dm +++ b/code/modules/client/preferences_mysql.dm @@ -28,7 +28,7 @@ be_special = sanitize_integer(be_special, 0, 65535, initial(be_special)) default_slot = sanitize_integer(default_slot, 1, MAX_SAVE_SLOTS, initial(default_slot)) toggles = sanitize_integer(toggles, 0, 65535, initial(toggles)) - sound = sanitize_integer(sound, 0, 65535, initial(toggles)) + sound = sanitize_integer(sound, 0, 65535, initial(sound)) UI_style_color = sanitize_hexcolor(UI_style_color, initial(UI_style_color)) UI_style_alpha = sanitize_integer(UI_style_alpha, 0, 255, initial(UI_style_alpha)) randomslot = sanitize_integer(randomslot, 0, 1, initial(randomslot)) @@ -186,7 +186,7 @@ firstquery.Execute() while(firstquery.NextRow()) if(text2num(firstquery.item[1]) == default_slot) - var/DBQuery/query = dbcon.NewQuery("UPDATE characters SET OOC_Notes='[sql_sanitize_text(metadata)]',real_name='[sql_sanitize_text(real_name)]',name_is_always_random='[be_random_name]',gender='[gender]',age='[age]',species='[sql_sanitize_text(species)]',language='[sql_sanitize_text(language)]',hair_red='[r_hair]',hair_green='[g_hair]',hair_blue='[b_hair]',facial_red='[r_facial]',facial_green='[g_facial]',facial_blue='[b_facial]',skin_tone='[s_tone]',skin_red='[r_skin]',skin_green='[g_skin]',skin_blue='[b_skin]',hair_style_name='[sql_sanitize_text(h_style)]',facial_style_name='[sql_sanitize_text(f_style)]',eyes_red='[r_eyes]',eyes_green='[g_eyes]',eyes_blue='[b_eyes]',underwear='[underwear]',undershirt='[undershirt]',backbag='[backbag]',b_type='[b_type]',alternate_option='[alternate_option]',job_support_high='[job_support_high]',job_support_med='[job_support_med]',job_support_low='[job_support_low]',job_medsci_high='[job_medsci_high]',job_medsci_med='[job_medsci_med]',job_medsci_low='[job_medsci_low]',job_engsec_high='[job_engsec_high]',job_engsec_med='[job_engsec_med]',job_engsec_low='[job_engsec_low]',job_karma_high='[job_karma_high]',job_karma_med='[job_karma_med]',job_karma_low='[job_karma_low]',flavor_text='[sql_sanitize_text(flavor_text)]',med_record='[sql_sanitize_text(med_record)]',sec_record='[sql_sanitize_text(sec_record)]',gen_record='[sql_sanitize_text(gen_record)]',player_alt_titles='[sql_sanitize_text(playertitlelist)]',be_special='[be_special]',disabilities='[disabilities]',organ_data='[organlist]',nanotrasen_relation='[nanotrasen_relation]', speciesprefs='[speciesprefs]' WHERE ckey='[C.ckey]' AND slot='[default_slot]'") + var/DBQuery/query = dbcon.NewQuery("UPDATE characters SET OOC_Notes='[sql_sanitize_text(metadata)]',real_name='[sql_sanitize_text(real_name)]',name_is_always_random='[be_random_name]',gender='[gender]',age='[age]',species='[sql_sanitize_text(species)]',language='[sql_sanitize_text(language)]',hair_red='[r_hair]',hair_green='[g_hair]',hair_blue='[b_hair]',facial_red='[r_facial]',facial_green='[g_facial]',facial_blue='[b_facial]',skin_tone='[s_tone]',skin_red='[r_skin]',skin_green='[g_skin]',skin_blue='[b_skin]',hair_style_name='[sql_sanitize_text(h_style)]',facial_style_name='[sql_sanitize_text(f_style)]',eyes_red='[r_eyes]',eyes_green='[g_eyes]',eyes_blue='[b_eyes]',underwear='[underwear]',undershirt='[undershirt]',backbag='[backbag]',b_type='[b_type]',alternate_option='[alternate_option]',job_support_high='[job_support_high]',job_support_med='[job_support_med]',job_support_low='[job_support_low]',job_medsci_high='[job_medsci_high]',job_medsci_med='[job_medsci_med]',job_medsci_low='[job_medsci_low]',job_engsec_high='[job_engsec_high]',job_engsec_med='[job_engsec_med]',job_engsec_low='[job_engsec_low]',job_karma_high='[job_karma_high]',job_karma_med='[job_karma_med]',job_karma_low='[job_karma_low]',flavor_text='[sql_sanitize_text(flavor_text)]',med_record='[sql_sanitize_text(med_record)]',sec_record='[sql_sanitize_text(sec_record)]',gen_record='[sql_sanitize_text(gen_record)]',player_alt_titles='[playertitlelist]',be_special='[be_special]',disabilities='[disabilities]',organ_data='[organlist]',nanotrasen_relation='[nanotrasen_relation]', speciesprefs='[speciesprefs]' WHERE ckey='[C.ckey]' AND slot='[default_slot]'") if(!query.Execute()) var/err = query.ErrorMsg() log_game("SQL ERROR during character slot saving. Error : \[[err]\]\n") diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm index 8b4b300a6b0..06c82bfc529 100644 --- a/code/modules/client/preferences_toggles.dm +++ b/code/modules/client/preferences_toggles.dm @@ -25,6 +25,16 @@ src << "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTRADIO) ? "hear all radio chat in the world" : "only hear from nearby speakers"]." prefs.save_preferences(src) feedback_add_details("admin_verb","TGR") + +/client/proc/toggle_hear_radio() + set name = "Show/Hide RadioChatter" + set category = "Preferences" + set desc = "Toggle seeing radiochatter from radios and speakers" + if(!holder) return + prefs.toggles ^= CHAT_RADIO + prefs.save_preferences(src) + usr << "You will [(prefs.toggles & CHAT_RADIO) ? "now" : "no longer"] see radio chatter from radios or speakers" + feedback_add_details("admin_verb","THR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/verb/toggleadminhelpsound() set name = "Hear/Silence Adminhelps" diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 9f3e9474fab..8c79383cc1a 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -79,20 +79,20 @@ ..() return - if(!canremove) + if(flags & NODROP) return var/obj/item/clothing/ears/O if(slot_flags & SLOT_TWOEARS ) O = (H.l_ear == src ? H.r_ear : H.l_ear) - user.u_equip(O) + user.unEquip(O) if(!istype(src,/obj/item/clothing/ears/offear)) del(O) O = src else O = src - user.u_equip(src) + user.unEquip(src) if (O) user.put_in_hands(O) @@ -160,7 +160,7 @@ BLIND // can't see anything var/clipped = 0 species_restricted = list("exclude","Unathi","Tajaran") -/obj/item/clothing/gloves/attackby(obj/item/weapon/W, mob/user) +/obj/item/clothing/gloves/attackby(obj/item/weapon/W, mob/user, params) if(istype(W, /obj/item/weapon/wirecutters)) if(clipped == 0) playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1) @@ -243,6 +243,37 @@ BLIND // can't see anything icon = 'icons/obj/clothing/masks.dmi' body_parts_covered = HEAD slot_flags = SLOT_MASK + var/mask_adjusted = 0 + var/ignore_maskadjust = 1 + var/adjusted_flags = null + +//Proc that moves gas/breath masks out of the way +/obj/item/clothing/mask/proc/adjustmask(var/mob/user) + if(!ignore_maskadjust) + if(!user.canmove || user.stat || user.restrained()) + return + if(src.mask_adjusted == 1) + src.icon_state = initial(icon_state) + gas_transfer_coefficient = initial(gas_transfer_coefficient) + permeability_coefficient = initial(permeability_coefficient) + user << "You push \the [src] back into place." + src.mask_adjusted = 0 + slot_flags = initial(slot_flags) + else + src.icon_state += "_up" + user << "You push \the [src] out of the way." + gas_transfer_coefficient = null + permeability_coefficient = null + src.mask_adjusted = 1 + if(adjusted_flags) + slot_flags = adjusted_flags + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(H.internal) + if(H.internals) + H.internals.icon_state = "internal0" + H.internal = null + usr.update_inv_wear_mask() //Shoes /obj/item/clothing/shoes @@ -267,7 +298,6 @@ BLIND // can't see anything icon = 'icons/obj/clothing/suits.dmi' name = "suit" var/fire_resist = T0C+100 - flags = FPRINT | TABLEPASS allowed = list(/obj/item/weapon/tank/emergency_oxygen) armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) slot_flags = SLOT_OCLOTHING @@ -281,7 +311,7 @@ BLIND // can't see anything name = "Space helmet" icon_state = "space" desc = "A special helmet designed for work in a hazardous, low-pressure environment." - flags = FPRINT | TABLEPASS | HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPSPRESSUREDMAGE + flags = HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPSPRESSUREDMAGE | THICKMATERIAL item_state = "s_helmet" permeability_coefficient = 0.01 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50) @@ -302,7 +332,7 @@ BLIND // can't see anything w_class = 4//bulky item gas_transfer_coefficient = 0.01 permeability_coefficient = 0.02 - flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE + flags = STOPSPRESSUREDMAGE | THICKMATERIAL body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit) slowdown = 2 @@ -321,7 +351,6 @@ BLIND // can't see anything name = "under" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS permeability_coefficient = 0.90 - flags = FPRINT | TABLEPASS slot_flags = SLOT_ICLOTHING armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) var/has_sensor = 1//For the crew computer 2 = unable to change mode @@ -331,31 +360,49 @@ BLIND // can't see anything 2 = Report detailed damages 3 = Report location */ - var/obj/item/clothing/tie/hastie = null + var/list/accessories = list() var/displays_id = 1 var/rolled_down = 0 var/basecolor +/obj/item/clothing/under/proc/can_attach_accessory(obj/item/clothing/accessory/A) + if(istype(A)) + .=1 + else + return 0 + if(accessories.len && (A.slot in list("utility","armband"))) + for(var/obj/item/clothing/accessory/AC in accessories) + if (AC.slot == A.slot) + return 0 -/obj/item/clothing/under/attackby(obj/item/I, mob/user) - if(!hastie && istype(I, /obj/item/clothing/tie)) - user.drop_item() - hastie = I - I.loc = src - user << "You attach [I] to [src]." +/obj/item/clothing/under/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/clothing/accessory)) + var/obj/item/clothing/accessory/A = I + if(can_attach_accessory(A)) + user.drop_item() + accessories += A + A.on_attached(src, user) - if(istype(loc, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = loc - H.update_inv_w_uniform() + if(istype(loc, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = loc + H.update_inv_w_uniform() + return + else + user << "You cannot attach more accessories of this type to [src]." + + if(accessories.len) + for(var/obj/item/clothing/accessory/A in accessories) + A.attackby(I, user, params) return ..() /obj/item/clothing/under/attack_hand(mob/user as mob) //only forward to the attached accessory if the clothing is equipped (not in a storage) - if(hastie && src.loc == user) - removetie() + if(accessories.len && src.loc == user) + for(var/obj/item/clothing/accessory/A in accessories) + A.attack_hand(user) return if ((ishuman(usr) || ismonkey(usr)) && src.loc == user) //make it harder to accidentally undress yourself @@ -369,13 +416,13 @@ BLIND // can't see anything if (!(src.loc == usr)) return - if (!( usr.restrained() ) && !( usr.stat )) + if (!( usr.restrained() ) && !( usr.stat ) && ( over_object )) switch(over_object.name) if("r_hand") - usr.u_equip(src) + usr.unEquip(src) usr.put_in_r_hand(src) if("l_hand") - usr.u_equip(src) + usr.unEquip(src) usr.put_in_l_hand(src) src.add_fingerprint(usr) return @@ -393,8 +440,9 @@ BLIND // can't see anything usr << "Its vital tracker appears to be enabled." if(3) usr << "Its vital tracker and tracking beacon appear to be enabled." - if(hastie) - usr << "\A [hastie] is clipped to it." + if(accessories.len) + for(var/obj/item/clothing/accessory/A in accessories) + usr << "\A [A] is attached to it." /obj/item/clothing/under/verb/toggle() set name = "Toggle Suit Sensors" @@ -439,30 +487,35 @@ BLIND // can't see anything else usr << "You cannot roll down the uniform!" -/obj/item/clothing/under/proc/removetie() +/obj/item/clothing/under/proc/remove_accessory(mob/user, obj/item/clothing/accessory/A) + if(!(A in accessories)) + return + + A.on_removed(user) + accessories -= A + usr.update_inv_w_uniform() + +/obj/item/clothing/under/verb/removetie() + set name = "Remove Accessory" + set category = "Object" set src in usr if(!istype(usr, /mob/living)) return if(usr.stat) return - - if(hastie) - usr.put_in_hands(hastie) - hastie = null - - if (istype(hastie,/obj/item/clothing/tie/storage)) - var/obj/item/clothing/tie/storage/W = hastie - if (W.hold) - W.hold.loc = hastie - - if(istype(loc, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = loc - H.update_inv_w_uniform() + if(!accessories.len) return + var/obj/item/clothing/accessory/A + if(accessories.len > 1) + A = input("Select an accessory to remove from [src]") as null|anything in accessories + else + A = accessories[1] + src.remove_accessory(usr,A) /obj/item/clothing/under/rank/New() sensor_mode = pick(0,1,2,3) ..() /obj/item/clothing/under/emp_act(severity) - if (hastie) - hastie.emp_act(severity) + if(accessories.len) + for(var/obj/item/clothing/accessory/A in accessories) + A.emp_act(severity) ..() diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index 4add6b97783..c787b1a17c5 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -35,7 +35,7 @@ desc = "An implanted replacement for a left eye with meson vision capabilities." icon_state = "cybereye-green" item_state = "eyepatch" - canremove = 0 + flags = NODROP /obj/item/clothing/glasses/science name = "Science Goggles" @@ -88,7 +88,7 @@ desc = "An implanted replacement for a left eye with material vision capabilities." icon_state = "cybereye-blue" item_state = "eyepatch" - canremove = 0 + flags = NODROP /obj/item/clothing/glasses/regular name = "Prescription Glasses" @@ -293,4 +293,4 @@ desc = "An implanted replacement for a left eye with thermal vision capabilities." icon_state = "cybereye-red" item_state = "eyepatch" - canremove = 0 + flags = NODROP diff --git a/code/modules/clothing/gloves/ninja.dm b/code/modules/clothing/gloves/ninja.dm index 4fbdcdf8607..5876067697b 100644 --- a/code/modules/clothing/gloves/ninja.dm +++ b/code/modules/clothing/gloves/ninja.dm @@ -102,7 +102,7 @@ drain("MECHA",A,suit) return 1 /* - if(istype(A,/obj/item/weapon/cell)) + if(istype(A,/obj/item/weapon/stock_parts/cell)) A.add_fingerprint(H) drain("CELL",A,suit) return 1 diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index 0ecd6fee1cf..42b985289a7 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -3,7 +3,6 @@ name = "hard hat" desc = "A piece of headgear used in dangerous working conditions to protect the head. Comes with a built-in flashlight." icon_state = "hardhat0_yellow" - flags = FPRINT | TABLEPASS item_state = "hardhat0_yellow" var/brightness_on = 4 //luminosity when on var/on = 0 @@ -48,7 +47,7 @@ item_state = "hardhat0_red" _color = "red" name = "firefighter helmet" - flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE + flags = STOPSPRESSUREDMAGE heat_protection = HEAD max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE cold_protection = HEAD @@ -58,7 +57,7 @@ icon_state = "hardhat0_white" item_state = "hardhat0_white" _color = "white" - flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE + flags = STOPSPRESSUREDMAGE heat_protection = HEAD max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE cold_protection = HEAD @@ -76,7 +75,7 @@ _color = "atmos" name = "atmospheric technician's firefighting helmet" desc = "A firefighter's helmet, able to keep the user cool in any situation." - flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE + flags = STOPSPRESSUREDMAGE flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE heat_protection = HEAD max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 31c58f8a943..c8d1f5d32c5 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -2,7 +2,7 @@ name = "helmet" desc = "Standard Security gear. Protects the head from impacts." icon_state = "helmet" - flags = FPRINT | TABLEPASS | HEADCOVERSEYES | HEADBANGPROTECT + flags = HEADCOVERSEYES | HEADBANGPROTECT item_state = "helmet" armor = list(melee = 50, bullet = 15, laser = 50,energy = 10, bomb = 25, bio = 0, rad = 0) flags_inv = HIDEEARS|HIDEEYES @@ -25,7 +25,7 @@ desc = "It's a helmet specifically designed to protect against close range attacks." icon_state = "riot" item_state = "helmet" - flags = FPRINT|TABLEPASS|HEADCOVERSEYES|HEADCOVERSMOUTH|HEADBANGPROTECT + flags = HEADCOVERSEYES | HEADCOVERSMOUTH | HEADBANGPROTECT armor = list(melee = 82, bullet = 15, laser = 5,energy = 5, bomb = 5, bio = 2, rad = 0) flags_inv = HIDEEARS siemens_coefficient = 0.7 @@ -34,7 +34,7 @@ name = "\improper SWAT helmet" desc = "They're often used by highly trained Swat Members." icon_state = "swat" - flags = FPRINT | TABLEPASS | HEADCOVERSEYES + flags = HEADCOVERSEYES item_state = "swat" armor = list(melee = 80, bullet = 60, laser = 50,energy = 25, bomb = 50, bio = 10, rad = 0) flags_inv = HIDEEARS|HIDEEYES @@ -54,7 +54,7 @@ name = "\improper Thunderdome helmet" desc = "'Let the battle commence!'" icon_state = "thunderdome" - flags = FPRINT | TABLEPASS | HEADCOVERSEYES + flags = HEADCOVERSEYES item_state = "thunderdome" armor = list(melee = 80, bullet = 60, laser = 50,energy = 10, bomb = 25, bio = 10, rad = 0) cold_protection = HEAD @@ -81,7 +81,7 @@ name = "gladiator helmet" desc = "Ave, Imperator, morituri te salutant." icon_state = "gladiator" - flags = FPRINT|TABLEPASS|HEADCOVERSEYES|BLOCKHAIR + flags = HEADCOVERSEYES | BLOCKHAIR item_state = "gladiator" flags_inv = HIDEMASK|HIDEEARS|HIDEEYES siemens_coefficient = 1 @@ -91,7 +91,7 @@ obj/item/clothing/head/helmet/redtaghelm name = "red laser tag helmet" desc = "They have chosen their own end." icon_state = "redtaghelm" - flags = FPRINT|TABLEPASS|HEADCOVERSEYES + flags = HEADCOVERSEYES item_state = "redtaghelm" armor = list(melee = 30, bullet = 10, laser = 20,energy = 10, bomb = 20, bio = 0, rad = 0) // Offer about the same protection as a hardhat. @@ -101,7 +101,7 @@ obj/item/clothing/head/helmet/bluetaghelm name = "blue laser tag helmet" desc = "They'll need more men." icon_state = "bluetaghelm" - flags = FPRINT|TABLEPASS|HEADCOVERSEYES + flags = HEADCOVERSEYES item_state = "bluetaghelm" armor = list(melee = 30, bullet = 10, laser = 20,energy = 10, bomb = 20, bio = 0, rad = 0) // Offer about the same protection as a hardhat. diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index e45e2556c7c..2908b473709 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -6,7 +6,6 @@ icon_state = "chef" item_state = "chef" desc = "The commander in chef's head wear." - flags = FPRINT | TABLEPASS siemens_coefficient = 0.9 loose = 35 // why-a do people always push-a me over @@ -15,7 +14,6 @@ name = "captain's hat" icon_state = "captain" desc = "It's good being the king." - flags = FPRINT|TABLEPASS item_state = "caphat" siemens_coefficient = 0.9 armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0) @@ -32,7 +30,6 @@ name = "head of personnel's cap" icon_state = "hopcap" desc = "The symbol of true bureaucratic micromanagement." - flags = FPRINT|TABLEPASS siemens_coefficient = 0.9 armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0) loose = 43 // not the answer @@ -42,7 +39,7 @@ name = "chaplain's hood" desc = "It's hood that covers the head. It keeps you warm during the space winters." icon_state = "chaplain_hood" - flags = FPRINT|TABLEPASS|HEADCOVERSEYES|BLOCKHAIR + flags = HEADCOVERSEYES | BLOCKHAIR siemens_coefficient = 0.9 loose = 2 @@ -51,7 +48,7 @@ name = "nun hood" desc = "Maximum piety in this star system." icon_state = "nun_hood" - flags = FPRINT|TABLEPASS|HEADCOVERSEYES|BLOCKHAIR + flags = HEADCOVERSEYES | BLOCKHAIR siemens_coefficient = 0.9 loose = 2 @@ -68,7 +65,6 @@ name = "beret" desc = "A beret, an artists favorite headwear." icon_state = "beret" - flags = FPRINT | TABLEPASS siemens_coefficient = 0.9 loose = 16 @@ -77,7 +73,6 @@ name = "head of security cap" desc = "The robust standard-issue cap of the Head of Security. For showing the officers who's in charge." icon_state = "hoscap" - flags = FPRINT | TABLEPASS armor = list(melee = 80, bullet = 60, laser = 50, energy = 10, bomb = 25, bio = 10, rad = 0) /obj/item/clothing/head/HoS/beret @@ -89,7 +84,6 @@ name = "warden's police hat" desc = "It's a special armored hat issued to the Warden of a security force. Protects the head from impacts." icon_state = "policehelm" - flags = FPRINT | TABLEPASS armor = list(melee = 60, bullet = 5, laser = 25, energy = 10, bomb = 25, bio = 0, rad = 0) /obj/item/clothing/head/customs @@ -98,14 +92,12 @@ icon_state = "customshelm" item_state = "customshelm" armor = list(melee = 30, bullet = 25, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0) - flags = FPRINT | TABLEPASS /obj/item/clothing/head/beret/sec name = "security beret" desc = "A beret with the security insignia emblazoned on it. For officers that are more inclined towards style than safety." icon_state = "beret_badge" armor = list(melee = 30, bullet = 25, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0) - flags = FPRINT | TABLEPASS /obj/item/clothing/head/beret/sec/warden name = "warden's beret" @@ -117,14 +109,13 @@ name = "engineering beret" desc = "A beret with the engineering insignia emblazoned on it. For engineers that are more inclined towards style than safety." icon_state = "e_beret_badge" - flags = FPRINT | TABLEPASS //Medical /obj/item/clothing/head/surgery name = "surgical cap" desc = "A cap surgeons wear during operations. Keeps their hair from tickling your internal organs." icon_state = "surgcap_blue" - flags = FPRINT | TABLEPASS | BLOCKHEADHAIR + flags = BLOCKHEADHAIR loose = 13 /obj/item/clothing/head/surgery/purple diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index 4f07b12eb37..e0741ed1ac7 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -4,7 +4,6 @@ name = "\improper CentComm. hat" icon_state = "centcom" desc = "It's good to be emperor." - flags = FPRINT|TABLEPASS item_state = "centhat" armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0) siemens_coefficient = 0.9 @@ -14,7 +13,6 @@ icon_state = "hairflower" desc = "Smells nice." item_state = "hairflower" - flags = FPRINT|TABLEPASS /obj/item/clothing/head/hairflower/purple icon_state = "hairflowerp" @@ -34,7 +32,6 @@ desc = "It's an amish looking hat." icon_state = "tophat" item_state = "that" - flags = FPRINT|TABLEPASS siemens_coefficient = 0.9 loose = 70 @@ -42,21 +39,18 @@ name = "redcoat's hat" icon_state = "redcoat" desc = "'I guess it's a redhead.'" - flags = FPRINT | TABLEPASS loose = 45 /obj/item/clothing/head/mailman name = "mailman's hat" icon_state = "mailman" desc = "'Right-on-time' mail service head wear." - flags = FPRINT | TABLEPASS loose = 65 /obj/item/clothing/head/plaguedoctorhat name = "plague doctor's hat" desc = "These were once used by Plague doctors. They're pretty much useless." icon_state = "plaguedoctor" - flags = FPRINT | TABLEPASS permeability_coefficient = 0.01 siemens_coefficient = 0.9 loose = 30 @@ -65,14 +59,13 @@ name = "hastur's hood" desc = "It's unspeakably stylish" icon_state = "hasturhood" - flags = FPRINT|TABLEPASS|HEADCOVERSEYES|BLOCKHAIR + flags = HEADCOVERSEYES | BLOCKHAIR loose = 1 /obj/item/clothing/head/nursehat name = "nurse's hat" desc = "It allows quick identification of trained medical personnel." icon_state = "nursehat" - flags = FPRINT|TABLEPASS siemens_coefficient = 0.9 loose = 80 // allowing for awkward come-ons when he/she drops his/her hat and you get it for him/her. @@ -81,7 +74,7 @@ icon_state = "syndicate-helm-black-red" item_state = "syndicate-helm-black-red" desc = "A plastic replica of a syndicate agent's space helmet, you'll look just like a real murderous syndicate agent in this! This is a toy, it is not made for use in space!" - flags = FPRINT | TABLEPASS | BLOCKHAIR + flags = BLOCKHAIR flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE siemens_coefficient = 2.0 loose = 15 // not a very good replica @@ -90,7 +83,7 @@ name = "cueball helmet" desc = "A large, featureless white orb mean to be worn on your head. How do you even see out of this thing?" icon_state = "cueball" - flags = FPRINT|TABLEPASS|HEADCOVERSEYES|HEADCOVERSMOUTH|BLOCKHAIR + flags = HEADCOVERSEYES | HEADCOVERSMOUTH | BLOCKHAIR item_state="cueball" flags_inv = 0 loose = 0 @@ -100,7 +93,6 @@ desc = "It's an amish looking armored top hat." icon_state = "tophat" item_state = "that" - flags = FPRINT|TABLEPASS flags_inv = 0 loose = 70 @@ -110,7 +102,6 @@ desc = "It's a green bandana with some fine nanotech lining." icon_state = "greenbandana" item_state = "greenbandana" - flags = FPRINT|TABLEPASS flags_inv = 0 loose = 1 @@ -119,7 +110,7 @@ desc = "A helmet made out of a box." icon_state = "cardborg_h" item_state = "cardborg_h" - flags = FPRINT | TABLEPASS | HEADCOVERSEYES | HEADCOVERSMOUTH + flags = HEADCOVERSEYES | HEADCOVERSMOUTH flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE loose = 20 @@ -128,7 +119,7 @@ desc = "fight for what's righteous!" icon_state = "justicered" item_state = "justicered" - flags = FPRINT|TABLEPASS|HEADCOVERSEYES|HEADCOVERSMOUTH|BLOCKHAIR + flags = HEADCOVERSEYES | HEADCOVERSMOUTH | BLOCKHAIR loose = 0 /obj/item/clothing/head/justice/blue @@ -151,7 +142,6 @@ name = "rabbit ears" desc = "Wearing these makes you looks useless, and only good for your sex appeal." icon_state = "bunny" - flags = FPRINT | TABLEPASS loose = 4 /obj/item/clothing/head/flatcap @@ -190,28 +180,24 @@ icon_state = "bowler_hat" item_state = "bowler_hat" desc = "For that industrial age look." - flags = FPRINT|TABLEPASS /obj/item/clothing/head/beaverhat name = "beaver hat" icon_state = "beaver_hat" item_state = "beaver_hat" desc = "Like a top hat, but made of beavers." - flags = FPRINT|TABLEPASS /obj/item/clothing/head/boaterhat name = "boater hat" icon_state = "boater_hat" item_state = "boater_hat" desc = "Goes well with celery." - flags = FPRINT|TABLEPASS /obj/item/clothing/head/fedora name = "\improper fedora" icon_state = "fedora" item_state = "fedora" desc = "A great hat ruined by being within fifty yards of you." - flags = FPRINT|TABLEPASS //TIPS FEDORA /obj/item/clothing/head/fedora/verb/tip_fedora() @@ -226,7 +212,6 @@ icon_state = "fez" item_state = "fez" desc = "Put it on your monkey, make lots of cash money." - flags = FPRINT|TABLEPASS //end bs12 hats @@ -235,7 +220,7 @@ desc = "Eeeee~heheheheheheh!" icon_state = "witch" item_state = "witch" - flags = FPRINT | TABLEPASS | BLOCKHAIR + flags = BLOCKHAIR siemens_coefficient = 2.0 loose = 1 @@ -244,7 +229,7 @@ desc = "Bkaw!" icon_state = "chickenhead" item_state = "chickensuit" - flags = FPRINT | TABLEPASS | BLOCKHAIR + flags = BLOCKHAIR siemens_coefficient = 2.0 /obj/item/clothing/head/corgi @@ -252,7 +237,7 @@ desc = "Woof!" icon_state = "corgihead" item_state = "chickensuit" - flags = FPRINT | TABLEPASS | BLOCKHAIR + flags = BLOCKHAIR siemens_coefficient = 2.0 /obj/item/clothing/head/bearpelt @@ -260,7 +245,7 @@ desc = "Fuzzy." icon_state = "bearpelt" item_state = "bearpelt" - flags = FPRINT | TABLEPASS | BLOCKHAIR + flags = BLOCKHAIR siemens_coefficient = 2.0 loose = 0 // grrrr @@ -269,7 +254,7 @@ icon_state = "xenos" item_state = "xenos_helm" desc = "A helmet made out of chitinous alien hide." - flags = FPRINT | TABLEPASS | BLOCKHAIR + flags = BLOCKHAIR flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE siemens_coefficient = 2.0 @@ -278,7 +263,6 @@ icon_state = "crown" item_state = "crown" desc = "A gliterring bananium crown with spessjewels in it. Swaggy." - flags = FPRINT | TABLEPASS /obj/item/clothing/head/fedora @@ -300,7 +284,7 @@ desc = "The typical clown soldier's helmet." icon_state = "stalhelm" item_state = "stalhelm" - flags = FPRINT | TABLEPASS | BLOCKHAIR + flags = BLOCKHAIR flags_inv = HIDEEARS /obj/item/clothing/head/panzer @@ -308,14 +292,14 @@ desc = "The softcap worn by HONK Mech pilots." icon_state = "panzercap" item_state = "panzercap" - flags = FPRINT | TABLEPASS | BLOCKHAIR + flags = BLOCKHAIR /obj/item/clothing/head/naziofficer name = "Clown Officer Cap" desc = "The peaked clown officer's cap, disturbingly similar to the warden's." icon_state = "officercap" item_state = "officercap" - flags = FPRINT | TABLEPASS | BLOCKHAIR + flags = BLOCKHAIR flags_inv = HIDEEARS /obj/item/clothing/head/beret/purple @@ -323,19 +307,16 @@ desc = " A purple beret, with a small golden crescent moon sewn onto it." icon_state = "purpleberet" item_state = "purpleberet" - flags = FPRINT | TABLEPASS /obj/item/clothing/head/beret/centcom/officer name = "officers beret" desc = "A black beret adorned with the shield—a silver kite shield with an engraved sword—of the Nanotrasen security forces, announcing to the world that the wearer is a defender of Nanotrasen." icon_state = "centcomofficerberet" - flags = FPRINT | TABLEPASS /obj/item/clothing/head/beret/centcom/captain name = "captains beret" desc = "A white beret adorned with the shield—a cobalt kite shield with an engraved sword—of the Nanotrasen security forces, worn only by those captaining a vessel of the Nanotrasen Navy." icon_state = "centcomcaptain" - flags = FPRINT | TABLEPASS /obj/item/clothing/head/sombrero name = "sombrero" @@ -354,4 +335,18 @@ icon_state = "shamebrero" item_state = "shamebrero" desc = "Once it's on, it never comes off." - canremove = 0 \ No newline at end of file + flags = NODROP + +/obj/item/clothing/head/griffin + name = "griffon head" + desc = "Why not 'eagle head'? Who knows." + icon_state = "griffinhat" + item_state = "griffinhat" + flags = BLOCKHAIR|NODROP + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE + +/obj/item/clothing/head/lordadmiralhat + name = "Lord Admiral's Hat" + desc = "A hat suitable for any man of high and exalted rank." + icon_state = "lordadmiralhat" + item_state = "lordadmiralhat" \ No newline at end of file diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index 80f321c4faf..92d71afc888 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -15,7 +15,7 @@ name = "welding helmet" desc = "A head-mounted face cover designed to protect the wearer completely from space-arc eye." icon_state = "welding" - flags = (FPRINT | TABLEPASS | HEADCOVERSEYES | HEADCOVERSMOUTH) + flags = HEADCOVERSEYES | HEADCOVERSMOUTH item_state = "welding" m_amt = 1750 g_amt = 400 @@ -60,7 +60,7 @@ name = "cake-hat" desc = "It's tasty looking!" icon_state = "cake0" - flags = FPRINT|TABLEPASS|HEADCOVERSEYES + flags = HEADCOVERSEYES var/onfire = 0.0 var/status = 0 var/fire_resist = T0C+1300 //this is the max temp it can stand before you start to cook. although it might not burn away, you take damage @@ -128,7 +128,7 @@ icon_state = "hardhat0_pumpkin"//Could stand to be renamed item_state = "hardhat0_pumpkin" _color = "pumpkin" - flags = FPRINT | TABLEPASS | HEADCOVERSEYES | HEADCOVERSMOUTH | BLOCKHAIR + flags = HEADCOVERSEYES | HEADCOVERSMOUTH | BLOCKHAIR flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE action_button_name = "Toggle Pumpkin Light" @@ -143,7 +143,6 @@ icon_state = "hardhat0_reindeer" item_state = "hardhat0_reindeer" _color = "reindeer" - flags = FPRINT | TABLEPASS flags_inv = 0 action_button_name = "Toggle Nose Light" armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) @@ -157,7 +156,6 @@ name = "kitty ears" desc = "A pair of kitty ears. Meow!" icon_state = "kitty" - flags = FPRINT | TABLEPASS var/icon/mob siemens_coefficient = 1.5 loose = 33 diff --git a/code/modules/clothing/head/soft_caps.dm b/code/modules/clothing/head/soft_caps.dm index 1020f95c79c..1f88aaa231c 100644 --- a/code/modules/clothing/head/soft_caps.dm +++ b/code/modules/clothing/head/soft_caps.dm @@ -2,7 +2,6 @@ name = "cargo cap" desc = "It's a baseball hat in a tasteless yellow colour." icon_state = "cargosoft" - flags = FPRINT|TABLEPASS item_state = "helmet" _color = "cargo" var/flipped = 0 diff --git a/code/modules/clothing/masks/boxing.dm b/code/modules/clothing/masks/boxing.dm index 1c84e97df5d..a461e0cf845 100644 --- a/code/modules/clothing/masks/boxing.dm +++ b/code/modules/clothing/masks/boxing.dm @@ -3,19 +3,26 @@ desc = "LOADSAMONEY" icon_state = "balaclava" item_state = "balaclava" - flags = FPRINT|TABLEPASS|BLOCKHAIR + flags = BLOCKHAIR flags_inv = HIDEFACE w_class = 2 + icon_action_button = "action_balaclava" + action_button_name = "Adjust Balaclava" + ignore_maskadjust = 0 species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/mask.dmi' ) + +/obj/item/clothing/mask/balaclava/attack_self(var/mob/user) + adjustmask(user) + /obj/item/clothing/mask/luchador name = "Luchador Mask" desc = "Worn by robust fighters, flying high to defeat their foes!" icon_state = "luchag" item_state = "luchag" - flags = FPRINT|TABLEPASS|BLOCKHAIR + flags = BLOCKHAIR flags_inv = HIDEFACE w_class = 2 siemens_coefficient = 3.0 diff --git a/code/modules/clothing/masks/breath.dm b/code/modules/clothing/masks/breath.dm index 25aff648f63..f3064e9f17b 100644 --- a/code/modules/clothing/masks/breath.dm +++ b/code/modules/clothing/masks/breath.dm @@ -3,39 +3,22 @@ name = "breath mask" icon_state = "breath" item_state = "breath" - flags = FPRINT | TABLEPASS | MASKCOVERSMOUTH | MASKINTERNALS + flags = MASKCOVERSMOUTH | MASKINTERNALS w_class = 2 gas_transfer_coefficient = 0.10 permeability_coefficient = 0.50 species_fit = list("Vox") - var/hanging = 0 + icon_action_button = "action_breath" + action_button_name = "Adjust Breath Mask" + ignore_maskadjust = 0 species_fit = list("Vox", "Vox Armalis") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/mask.dmi', "Vox Armalis" = 'icons/mob/species/armalis/mask.dmi', ) - - verb/toggle() - set category = "Object" - set name = "Adjust mask" - set src in usr - - if(usr.canmove && !usr.stat && !usr.restrained()) - if(!src.hanging) - src.hanging = !src.hanging - gas_transfer_coefficient = 1 //gas is now escaping to the turf and vice versa - flags &= ~(MASKCOVERSMOUTH | MASKINTERNALS) - icon_state = "[initial(icon_state)]down" - usr << "Your mask is now hanging on your neck." - - else - src.hanging = !src.hanging - gas_transfer_coefficient = 0.10 - flags |= MASKCOVERSMOUTH | MASKINTERNALS - icon_state = "[initial(icon_state)]" - usr << "You pull the mask up to cover your face." - usr.update_inv_wear_mask() +/obj/item/clothing/mask/breath/attack_self(var/mob/user) + adjustmask(user) /obj/item/clothing/mask/breath/medical desc = "A close-fitting sterile mask that can be connected to an air supply." @@ -52,3 +35,6 @@ item_state = "voxmask" permeability_coefficient = 0.01 species_restricted = list("Vox") + icon_action_button = null + action_button_name = null + ignore_maskadjust = 1 diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index 2ad9f030cf2..d3030eec675 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -2,7 +2,7 @@ name = "gas mask" desc = "A face-covering mask that can be connected to an air supply." icon_state = "gas_alt" - flags = FPRINT | TABLEPASS | MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS + flags = MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS flags_inv = HIDEEARS|HIDEEYES|HIDEFACE w_class = 3.0 item_state = "gas_alt" @@ -19,7 +19,7 @@ name = "bane mask" desc = "Only when the station is in flames, do you have my permission to robust." icon_state = "bane_mask" - flags = FPRINT | TABLEPASS | MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS + flags = MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS flags_inv = HIDEEARS|HIDEEYES|HIDEFACE w_class = 3.0 item_state = "bane_mask" @@ -51,51 +51,13 @@ siemens_coefficient = 0.7 species_fit = list("Vox") -/obj/item/clothing/mask/gas/voice - name = "gas mask" - //desc = "A face-covering mask that can be connected to an air supply. It seems to house some odd electronics." - var/mode = 0// 0==Scouter | 1==Night Vision | 2==Thermal | 3==Meson - var/voice = "Unknown" - var/vchange = 0//This didn't do anything before. It now checks if the mask has special functions/N - origin_tech = "syndicate=4" - species_fit = list("Vox") - -/obj/item/clothing/mask/gas/voice/space_ninja - name = "ninja mask" - desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement." - icon_state = "s-ninja(norm)" - item_state = "s-ninja_mask" - vchange = 1 - unacidable = 1 - siemens_coefficient = 0.2 - species_fit = list("Vox") - -/obj/item/clothing/mask/gas/voice/space_ninja/scar - name = "ninja mask" - desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement. This mask appears to have already seen battle." - icon_state = "s-ninja(scar)" - item_state = "s-ninja_mask" - -/obj/item/clothing/mask/gas/voice/space_ninja/visor - name = "ninja mask" - desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement. This variant appears to have a visor to increase vision." - icon_state = "s-ninja(visor)" - item_state = "s-ninja_mask" - -/obj/item/clothing/mask/gas/voice/space_ninja/monocular - name = "ninja mask" - desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement. This variant appears to focus the user's vision out of a single port." - icon_state = "s-ninja(mon)" - item_state = "s-ninja_mask" - - /obj/item/clothing/mask/gas/clown_hat name = "clown wig and mask" desc = "A true prankster's facial attire. A clown is incomplete without his wig and mask." icon_state = "clown" item_state = "clown_hat" species_fit = list("Vox") - flags = FPRINT | TABLEPASS | MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS | BLOCKHAIR + flags = MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS | BLOCKHAIR /obj/item/clothing/mask/gas/clown_hat/attack_self(mob/user) @@ -118,7 +80,7 @@ desc = "Some pranksters are truly magical." icon_state = "wizzclown" item_state = "wizzclown" - flags = FPRINT | TABLEPASS | MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS | BLOCKHAIR + flags = MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS | BLOCKHAIR /obj/item/clothing/mask/gas/virusclown_hat name = "clown wig and mask" @@ -173,6 +135,7 @@ desc = "Twoooo!" icon_state = "owl" species_fit = list("Vox") + flags = MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS | NODROP // ******************************************************************** @@ -183,20 +146,40 @@ name = "security gas mask" desc = "A standard issue Security gas mask with integrated 'Compli-o-nator 3000' device, plays over a dozen pre-recorded compliance phrases designed to get scumbags to stand still whilst you taze them. Do not tamper with the device." action_button_name = "HALT!" - icon_state = "officermask" + icon_state = "sechailer" var/cooldown = 0 var/aggressiveness = 2 + ignore_maskadjust = 0 species_fit = list() action_button_name = "HALT!" - icon_action_button = "action_officermask" + icon_action_button = "action_sechailer" -/obj/item/clothing/mask/gas/sechailer/warden - icon_state = "wardenmask" +/obj/item/clothing/mask/gas/sechailer/swat + name = "\improper SWAT mask" + desc = "A close-fitting tactical mask with an especially aggressive Compli-o-nator 3000." + action_button_name = "HALT!" + icon_state = "officermask" + aggressiveness = 3 + ignore_maskadjust = 1 -/obj/item/clothing/mask/gas/sechailer/hos - icon_state = "hosmask" +/obj/item/clothing/mask/gas/sechailer/cyborg + name = "security hailer" + desc = "A set of recognizable pre-recorded messages for cyborgs to use when apprehending criminals." + icon = 'icons/obj/device.dmi' + icon_state = "taperecorderidle" + aggressiveness = 1 //Borgs are nicecurity! + ignore_maskadjust = 1 -/obj/item/clothing/mask/gas/sechailer/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/clothing/mask/gas/sechailer/cyborg/New() + ..() + verbs -= /obj/item/clothing/mask/gas/sechailer/verb/adjust + +/obj/item/clothing/mask/gas/sechailer/verb/adjust() + set category = "Object" + set name = "Adjust Mask" + adjustmask(usr) + +/obj/item/clothing/mask/gas/sechailer/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/screwdriver)) switch(aggressiveness) if(1) diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm index b1f7ba41c3b..220931d805e 100644 --- a/code/modules/clothing/masks/miscellaneous.dm +++ b/code/modules/clothing/masks/miscellaneous.dm @@ -3,7 +3,7 @@ desc = "To stop that awful noise." icon_state = "muzzle" item_state = "muzzle" - flags = FPRINT|TABLEPASS|MASKCOVERSMOUTH + flags = MASKCOVERSMOUTH w_class = 2 gas_transfer_coefficient = 0.90 species_fit = list("Vox") @@ -31,19 +31,25 @@ icon_state = "sterile" item_state = "sterile" w_class = 1 - flags = FPRINT|TABLEPASS|MASKCOVERSMOUTH + flags = MASKCOVERSMOUTH gas_transfer_coefficient = 0.90 permeability_coefficient = 0.01 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 25, rad = 0) + action_button_name = "Adjust Sterile Mask" + icon_action_button = "action_sterile" + ignore_maskadjust = 0 species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/mask.dmi' ) + +/obj/item/clothing/mask/surgical/attack_self(var/mob/user) + adjustmask(user) + /obj/item/clothing/mask/fakemoustache name = "fake moustache" desc = "Warning: moustache is fake." icon_state = "fake-moustache" - flags = FPRINT|TABLEPASS flags_inv = HIDEFACE //scarves (fit in in mask slot) @@ -53,7 +59,7 @@ desc = "A blue neck scarf." icon_state = "blueneckscarf" item_state = "blueneckscarf" - flags = FPRINT|TABLEPASS|MASKCOVERSMOUTH + flags = MASKCOVERSMOUTH w_class = 2 gas_transfer_coefficient = 0.90 @@ -62,7 +68,7 @@ desc = "A red and white checkered neck scarf." icon_state = "redwhite_scarf" item_state = "redwhite_scarf" - flags = FPRINT|TABLEPASS|MASKCOVERSMOUTH + flags = MASKCOVERSMOUTH w_class = 2 gas_transfer_coefficient = 0.90 @@ -71,7 +77,7 @@ desc = "A green neck scarf." icon_state = "green_scarf" item_state = "green_scarf" - flags = FPRINT|TABLEPASS|MASKCOVERSMOUTH + flags = MASKCOVERSMOUTH w_class = 2 gas_transfer_coefficient = 0.90 @@ -80,7 +86,7 @@ desc = "A stealthy, dark scarf." icon_state = "ninja_scarf" item_state = "ninja_scarf" - flags = FPRINT|TABLEPASS|MASKCOVERSMOUTH + flags = MASKCOVERSMOUTH w_class = 2 gas_transfer_coefficient = 0.90 siemens_coefficient = 0 @@ -90,7 +96,7 @@ desc = "A rubber pig mask." icon_state = "pig" item_state = "pig" - flags = FPRINT|TABLEPASS|BLOCKHAIR + flags = BLOCKHAIR flags_inv = HIDEFACE w_class = 2 siemens_coefficient = 0.9 @@ -101,7 +107,7 @@ desc = "A mask made of soft vinyl and latex, representing the head of a horse." icon_state = "horsehead" item_state = "horsehead" - flags = FPRINT|TABLEPASS|BLOCKHAIR + flags = BLOCKHAIR flags_inv = HIDEFACE w_class = 2 siemens_coefficient = 0.9 @@ -112,7 +118,7 @@ /obj/item/clothing/mask/horsehead/equipped(mob/user, slot) - if(!canremove) //cursed masks only + if(flags & NODROP) //cursed masks only originalname = user.real_name if(!user.real_name || user.real_name == "Unknown") user.real_name = "A Horse With No Name" //it felt good to be out of the rain @@ -121,12 +127,12 @@ ..() /obj/item/clothing/mask/horsehead/dropped() //this really shouldn't happen, but call it extreme caution - if(!canremove) + if(flags & NODROP) goodbye_horses(loc) ..() /obj/item/clothing/mask/horsehead/Destroy() - if(!canremove) + if(flags & NODROP) goodbye_horses(loc) ..() @@ -150,4 +156,52 @@ icon_state = "pennywise_mask" item_state = "pennywise_mask" species_fit = list("Vox") - flags = FPRINT | TABLEPASS | MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS | BLOCKHAIR + flags = MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS | BLOCKHAIR + +// Bandanas +/obj/item/clothing/mask/bandana + name = "bandana" + desc = "A colorful bandana." + flags = MASKCOVERSMOUTH + flags_inv = HIDEFACE + w_class = 1 + slot_flags = SLOT_MASK + ignore_maskadjust = 0 + adjusted_flags = SLOT_HEAD + icon_state = "bandbotany" + icon_action_button = "action_bandbotany" + action_button_name = "Adjust Bandana" + +/obj/item/clothing/mask/bandana/attack_self(var/mob/user) + adjustmask(user) + +obj/item/clothing/mask/bandana/red + name = "red bandana" + icon_state = "bandred" + +obj/item/clothing/mask/bandana/blue + name = "blue bandana" + icon_state = "bandblue" + +obj/item/clothing/mask/bandana/gold + name = "gold bandana" + icon_state = "bandgold" + +obj/item/clothing/mask/bandana/green + name = "green bandana" + icon_state = "bandgreen" + +/obj/item/clothing/mask/bandana/botany + name = "botany bandana" + desc = "It's a green bandana with some fine nanotech lining." + icon_state = "bandbotany" + +/obj/item/clothing/mask/bandana/skull + name = "skull bandana" + desc = "It's a black bandana with a skull pattern." + icon_state = "bandskull" + +/obj/item/clothing/mask/bandana/black + name = "black bandana" + desc = "It's a black bandana." + icon_state = "bandblack" \ No newline at end of file diff --git a/code/modules/clothing/masks/voice.dm b/code/modules/clothing/masks/voice.dm new file mode 100644 index 00000000000..dc26b507025 --- /dev/null +++ b/code/modules/clothing/masks/voice.dm @@ -0,0 +1,59 @@ +/obj/item/voice_changer + name = "voice changer" + desc = "A voice scrambling module. If you can see this, report it as a bug on the tracker." + var/voice //If set and item is present in mask/suit, this name will be used for the wearer's speech. + var/active + +/obj/item/clothing/mask/gas/voice + name = "gas mask" +// desc = "A face-covering mask that can be connected to an air supply. It seems to house some odd electronics." + var/obj/item/voice_changer/changer + origin_tech = "syndicate=4" + +/obj/item/clothing/mask/gas/voice/verb/Toggle_Voice_Changer() + set category = "Object" + set src in usr + + changer.active = !changer.active + usr << "You [changer.active ? "enable" : "disable"] the voice-changing module in \the [src]." + +/obj/item/clothing/mask/gas/voice/verb/Set_Voice(name as text) + set category = "Object" + set src in usr + + var/voice = sanitize(copytext(name,1,MAX_MESSAGE_LEN)) + if(!voice || !length(voice)) return + changer.voice = voice + usr << "You are now mimicking [changer.voice]." + +/obj/item/clothing/mask/gas/voice/New() + ..() + changer = new(src) + +/obj/item/clothing/mask/gas/voice/space_ninja + name = "ninja mask" + desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement." + icon_state = "s-ninja(norm)" + item_state = "s-ninja_mask" + unacidable = 1 + siemens_coefficient = 0.2 + species_fit = list("Vox") + var/mode = 0// 0==Scouter | 1==Night Vision | 2==Thermal | 3==Meson + +/obj/item/clothing/mask/gas/voice/space_ninja/scar + name = "ninja mask" + desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement. This mask appears to have already seen battle." + icon_state = "s-ninja(scar)" + item_state = "s-ninja_mask" + +/obj/item/clothing/mask/gas/voice/space_ninja/visor + name = "ninja mask" + desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement. This variant appears to have a visor to increase vision." + icon_state = "s-ninja(visor)" + item_state = "s-ninja_mask" + +/obj/item/clothing/mask/gas/voice/space_ninja/monocular + name = "ninja mask" + desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement. This variant appears to focus the user's vision out of a single port." + icon_state = "s-ninja(mon)" + item_state = "s-ninja_mask" \ No newline at end of file diff --git a/code/modules/clothing/shoes/colour.dm b/code/modules/clothing/shoes/colour.dm index ad1ebc9a96d..ef92c5837df 100644 --- a/code/modules/clothing/shoes/colour.dm +++ b/code/modules/clothing/shoes/colour.dm @@ -93,13 +93,13 @@ if (src.chained) src.chained = null src.slowdown = SHOES_SLOWDOWN - new /obj/item/weapon/handcuffs( user.loc ) + new /obj/item/weapon/restraints/handcuffs( user.loc ) src.icon_state = "orange" return -/obj/item/clothing/shoes/orange/attackby(H as obj, loc) +/obj/item/clothing/shoes/orange/attackby(H as obj, loc, params) ..() - if ((istype(H, /obj/item/weapon/handcuffs) && !( src.chained ))) + if ((istype(H, /obj/item/weapon/restraints/handcuffs) && !( src.chained ))) //H = null if (src.icon_state != "orange") return del(H) diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index 4c08bba5f4b..255bccf8a81 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -150,4 +150,11 @@ /obj/item/clothing/shoes/centcom name = "dress shoes" desc = "They appear impeccably polished." - icon_state = "laceups" \ No newline at end of file + icon_state = "laceups" + +/obj/item/clothing/shoes/griffin + name = "griffon boots" + desc = "A pair of costume boots fashioned after bird talons." + icon_state = "griffinboots" + item_state = "griffinboots" + flags = NODROP \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/alien.dm b/code/modules/clothing/spacesuits/alien.dm index d1d9962393b..d367671e34f 100644 --- a/code/modules/clothing/spacesuits/alien.dm +++ b/code/modules/clothing/spacesuits/alien.dm @@ -83,7 +83,7 @@ // Can't be equipped by any other species due to bone structure and vox cybernetics. /obj/item/clothing/suit/space/vox w_class = 3 - allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs,/obj/item/weapon/tank) + allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank) slowdown = 2 armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) siemens_coefficient = 0.6 @@ -204,7 +204,7 @@ if(src.magpulse) flags &= ~NOSLIP magpulse = 0 - canremove = 1 + flags |= NODROP user << "You relax your deathgrip on the flooring." else //make sure these can only be used when equipped. @@ -218,7 +218,7 @@ flags |= NOSLIP magpulse = 1 - canremove = 0 //kinda hard to take off magclaws when you are gripping them tightly. + flags &= ~NODROP //kinda hard to take off magclaws when you are gripping them tightly. user << "You dig your claws deeply into the flooring, bracing yourself." user << "It would be hard to take off the [src] without relaxing your grip first." @@ -229,7 +229,7 @@ user.visible_message("The [src] go limp as they are removed from [usr]'s feet.", "The [src] go limp as they are removed from your feet.") flags &= ~NOSLIP magpulse = 0 - canremove = 1 + flags &= ~NODROP /obj/item/clothing/shoes/magboots/vox/examine() set src in view() @@ -256,54 +256,3 @@ "Vox" = 'icons/mob/species/vox/head.dmi', "Vox Armalis" = 'icons/mob/species/armalis/head.dmi', ) - -/obj/item/clothing/suit/space/plasmaman - w_class = 3 - allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box/magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs,/obj/item/weapon/tank) - slowdown = 2 - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 0) - heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS - flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT - max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE - species_restricted = list("Plasmaman") - flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE | PLASMAGUARD - - icon_state = "plasmaman_suit" - item_state = "plasmaman_suit" - -/obj/item/clothing/head/helmet/space/plasmaman - flags = FPRINT | TABLEPASS | HEADCOVERSEYES | BLOCKHAIR | STOPSPRESSUREDMAGE | PLASMAGUARD - species_restricted = list("Plasmaman") - - icon_state = "plasmaman_helmet0" - item_state = "plasmaman_helmet0" - var/brightness_on = 4 //luminosity when on - var/on = 0 - var/no_light=0 // Disable the light on the atmos suit - action_button_name = "Toggle Helmet Light" - - attack_self(mob/user) - if(!isturf(user.loc)) - user << "You cannot turn the light on while in this [user.loc]" //To prevent some lighting anomalities. - return - if(no_light) - return - on = !on - icon_state = "plasmaman_helmet[on]" -// item_state = "rig[on]-[_color]" - - if(on) user.SetLuminosity(user.luminosity + brightness_on) - else user.SetLuminosity(user.luminosity - brightness_on) - - pickup(mob/user) - if(on) - user.SetLuminosity(user.luminosity + brightness_on) -// user.UpdateLuminosity() - SetLuminosity(0) - - dropped(mob/user) - if(on) - user.SetLuminosity(user.luminosity - brightness_on) -// user.UpdateLuminosity() - SetLuminosity(brightness_on) \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/breaches.dm b/code/modules/clothing/spacesuits/breaches.dm index 5bc1ecaf5ab..0c83d8e7464 100644 --- a/code/modules/clothing/spacesuits/breaches.dm +++ b/code/modules/clothing/spacesuits/breaches.dm @@ -174,7 +174,7 @@ var/global/list/breach_burn_descriptors = list( //Handles repairs (and also upgrades). -/obj/item/clothing/suit/space/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/clothing/suit/space/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W,/obj/item/stack/sheet/mineral/plastic) || istype(W,/obj/item/stack/sheet/metal)) if(istype(src.loc,/mob/living)) diff --git a/code/modules/clothing/spacesuits/captain.dm b/code/modules/clothing/spacesuits/captain.dm index 62d21b3688d..9e581c1519e 100644 --- a/code/modules/clothing/spacesuits/captain.dm +++ b/code/modules/clothing/spacesuits/captain.dm @@ -4,7 +4,7 @@ icon_state = "capspace" item_state = "capspacehelmet" desc = "A special helmet designed for work in a hazardous, low-pressure environment. Only for the most fashionable of military figureheads." - flags = FPRINT | TABLEPASS | HEADCOVERSEYES | BLOCKHAIR | STOPSPRESSUREDMAGE|HEADCOVERSMOUTH + flags = HEADCOVERSEYES | BLOCKHAIR | STOPSPRESSUREDMAGE|HEADCOVERSMOUTH flags_inv = HIDEFACE permeability_coefficient = 0.01 armor = list(melee = 65, bullet = 50, laser = 50,energy = 25, bomb = 50, bio = 100, rad = 50) @@ -18,9 +18,9 @@ w_class = 4 gas_transfer_coefficient = 0.01 permeability_coefficient = 0.02 - flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE | ONESIZEFITSALL + flags = STOPSPRESSUREDMAGE | ONESIZEFITSALL body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS - allowed = list(/obj/item/weapon/tank/emergency_oxygen, /obj/item/device/flashlight,/obj/item/weapon/gun/energy, /obj/item/weapon/gun/projectile, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs) + allowed = list(/obj/item/weapon/tank/emergency_oxygen, /obj/item/device/flashlight,/obj/item/weapon/gun/energy, /obj/item/weapon/gun/projectile, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs) slowdown = 1.5 armor = list(melee = 65, bullet = 50, laser = 50, energy = 25, bomb = 50, bio = 100, rad = 50) flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT||HIDETAIL diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm index f1875e34de1..4d6035ba2fe 100644 --- a/code/modules/clothing/spacesuits/chronosuit.dm +++ b/code/modules/clothing/spacesuits/chronosuit.dm @@ -139,9 +139,9 @@ if(user.head && istype(user.head, /obj/item/clothing/head/helmet/space/chronos)) user << "\[ ok \] Mounting /dev/helmet" helmet = user.head - helmet.canremove = 0 + helmet.flags |= NODROP helmet.suit = src - src.canremove = 0 + src.flags |= NODROP user << "\[ ok \] Starting brainwave scanner" user << "\[ ok \] Starting ui display driver" user << "\[ ok \] Initializing chronowalk4-view" @@ -169,11 +169,11 @@ user << "\[ ok \] Stopping ui display driver" user << "\[ ok \] Stopping brainwave scanner" user << "\[ ok \] Unmounting /dev/helmet" - helmet.canremove = 1 + helmet.flags &= ~NODROP helmet.suit = null helmet = null user << "logout" - src.canremove = 1 + src.flags &= ~NODROP cooldown = world.time + cooldowntime * 1.5 activated = 0 activating = 0 diff --git a/code/modules/clothing/spacesuits/ert.dm b/code/modules/clothing/spacesuits/ert.dm index 1dd56938504..947c4b0441c 100644 --- a/code/modules/clothing/spacesuits/ert.dm +++ b/code/modules/clothing/spacesuits/ert.dm @@ -5,6 +5,7 @@ item_state = "helm-command" armor = list(melee = 50, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 60) siemens_coefficient = 0.6 + rig_restrict_helmet = 0 // ERT helmets can be taken on and off at will. var/obj/machinery/camera/camera /obj/item/clothing/head/helmet/space/rig/ert/attack_self(mob/user) @@ -28,7 +29,7 @@ icon_state = "ert_commander" item_state = "suit-command" w_class = 3 - allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs,/obj/item/weapon/tank) + allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank) slowdown = 1 armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 60) allowed = list(/obj/item/device/flashlight, /obj/item/weapon/tank, /obj/item/device/t_scanner, /obj/item/weapon/rcd, /obj/item/weapon/crowbar, \ diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index b47cca56802..5379e5e77ca 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -14,7 +14,7 @@ icon_state = "caparmor" item_state = "capspacesuit" w_class = 4 - allowed = list(/obj/item/weapon/tank, /obj/item/device/flashlight,/obj/item/weapon/gun/energy, /obj/item/weapon/gun/projectile, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs) + allowed = list(/obj/item/weapon/tank, /obj/item/device/flashlight,/obj/item/weapon/gun/energy, /obj/item/weapon/gun/projectile, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs) slowdown = 1 armor = list(melee = 65, bullet = 50, laser = 50, energy = 25, bomb = 50, bio = 100, rad = 50) siemens_coefficient = 0.7 @@ -35,7 +35,7 @@ desc = "A heavily armored, advanced space suit that protects against most forms of damage." icon_state = "deathsquad" item_state = "swat_suit" - allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank) + allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank) armor = list(melee = 80, bullet = 80, laser = 50,energy = 50, bomb = 100, bio = 100, rad = 100) slowdown = 1 max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT @@ -64,7 +64,7 @@ name = "Santa's hat" desc = "Ho ho ho. Merrry X-mas!" icon_state = "santahat" - flags = FPRINT | TABLEPASS | HEADCOVERSEYES | BLOCKHAIR | STOPSPRESSUREDMAGE + flags = HEADCOVERSEYES | BLOCKHAIR | STOPSPRESSUREDMAGE /obj/item/clothing/suit/space/santa name = "Santa's suit" @@ -72,7 +72,7 @@ icon_state = "santa" item_state = "santa" slowdown = 0 - flags = FPRINT | TABLEPASS | ONESIZEFITSALL | STOPSPRESSUREDMAGE + flags = ONESIZEFITSALL | STOPSPRESSUREDMAGE allowed = list(/obj/item) //for stuffing exta special presents @@ -83,7 +83,7 @@ icon_state = "pirate" item_state = "pirate" armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) - flags = FPRINT | TABLEPASS | HEADCOVERSEYES | BLOCKHAIR | STOPSPRESSUREDMAGE + flags = HEADCOVERSEYES | BLOCKHAIR | STOPSPRESSUREDMAGE siemens_coefficient = 0.9 /obj/item/clothing/suit/space/pirate @@ -92,7 +92,7 @@ icon_state = "pirate" item_state = "pirate" w_class = 3 - allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank) + allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank) slowdown = 0 armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) siemens_coefficient = 0.9 diff --git a/code/modules/clothing/spacesuits/ninja.dm b/code/modules/clothing/spacesuits/ninja.dm index 3f162fbf09e..34df11c3f2c 100644 --- a/code/modules/clothing/spacesuits/ninja.dm +++ b/code/modules/clothing/spacesuits/ninja.dm @@ -3,7 +3,7 @@ name = "ninja hood" icon_state = "s-ninja" item_state = "s-ninja_hood" - allowed = list(/obj/item/weapon/cell) + allowed = list(/obj/item/weapon/stock_parts/cell) armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 25) unacidable = 1 siemens_coefficient = 0.2 @@ -14,7 +14,7 @@ desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins." icon_state = "s-ninja" item_state = "s-ninja_suit" - allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank,/obj/item/weapon/cell,/obj/item/device/suit_cooling_unit) + allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank,/obj/item/weapon/stock_parts/cell,/obj/item/device/suit_cooling_unit) slowdown = 0 unacidable = 1 armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) @@ -22,7 +22,7 @@ //Important parts of the suit. var/mob/living/carbon/affecting = null//The wearer. - var/obj/item/weapon/cell/cell//Starts out with a high-capacity cell using New(). + var/obj/item/weapon/stock_parts/cell/cell//Starts out with a high-capacity cell using New(). var/datum/effect/effect/system/spark_spread/spark_system//To create sparks. var/reagent_list[] = list("tricordrazine","dexalinp","spaceacillin","anti_toxin","nutriment","uranium","hyronalin")//The reagents ids which are added to the suit at New(). var/stored_research[]//For stealing station research. diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm new file mode 100644 index 00000000000..6c20fbae7ee --- /dev/null +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -0,0 +1,170 @@ +// PLASMEN SHIT +// CAN'T WEAR UNLESS YOU'RE A PINK SKELLINGTON +/obj/item/clothing/suit/space/eva/plasmaman + w_class = 3 + allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank) + slowdown = 2 + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 0) + heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS + flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE + species_restricted = list("Plasmaman") + flags = STOPSPRESSUREDMAGE | PLASMAGUARD + + icon_state = "plasmaman_suit" + item_state = "plasmaman_suit" + + var/next_extinguish=0 + var/extinguish_cooldown=10 SECONDS + var/extinguishes_left=10 // Yeah yeah, reagents, blah blah blah. This should be simple. + +/obj/item/clothing/suit/space/eva/plasmaman/examine() + set src in view() + ..() + usr << "There are [extinguishes_left] extinguisher canisters left in this suit." +/obj/item/clothing/suit/space/eva/plasmaman/proc/Extinguish(var/mob/user) + var/mob/living/carbon/human/H=user + if(extinguishes_left) + if(next_extinguish > world.time) + return + + next_extinguish = world.time + extinguish_cooldown + extinguishes_left-- + H << "Your suit automatically extinguishes the fire." + H.ExtinguishMob() + +/obj/item/clothing/head/helmet/space/eva/plasmaman + flags = HEADCOVERSEYES | BLOCKHAIR | STOPSPRESSUREDMAGE | PLASMAGUARD + species_restricted = list("Plasmaman") + + icon_state = "plasmaman_helmet0" + item_state = "plasmaman_helmet0" + var/base_state = "plasmaman_helmet" + var/brightness_on = 4 //luminosity when on + var/on = 0 + var/no_light=0 // Disable the light on the atmos suit + action_button_name = "Toggle Helmet Light" + +/obj/item/clothing/head/helmet/space/eva/plasmaman/attack_self(mob/user) + if(!isturf(user.loc)) + user << "You cannot turn the light on while in this [user.loc]" //To prevent some lighting anomalities. + return + if(no_light) + return + on = !on + icon_state = "[base_state][on]" +// item_state = "rig[on]-[_color]" + if(on) user.SetLuminosity(user.luminosity + brightness_on) + else user.SetLuminosity(user.luminosity - brightness_on) + +/obj/item/clothing/head/helmet/space/eva/plasmaman/pickup(mob/user) + if(on) + user.SetLuminosity(user.luminosity + brightness_on) +// user.UpdateLuminosity() + SetLuminosity(0) + +/obj/item/clothing/head/helmet/space/eva/plasmaman/dropped(mob/user) + if(on) + user.SetLuminosity(user.luminosity - brightness_on) +// user.UpdateLuminosity() + SetLuminosity(brightness_on) + + + +// ENGINEERING +/obj/item/clothing/suit/space/eva/plasmaman/assistant + icon_state = "plasmamanAssistant_suit" + +/obj/item/clothing/head/helmet/space/eva/plasmaman/assistant + icon_state = "plasmamanAssistant_helmet0" + base_state = "plasmamanAssistant_helmet" + +/obj/item/clothing/suit/space/eva/plasmaman/atmostech + icon_state = "plasmamanAtmos_suit" + +/obj/item/clothing/head/helmet/space/eva/plasmaman/atmostech + icon_state = "plasmamanAtmos_helmet0" + base_state = "plasmamanAtmos_helmet" + +/obj/item/clothing/suit/space/eva/plasmaman/engineer + icon_state = "plasmamanEngineer_suit" + +/obj/item/clothing/head/helmet/space/eva/plasmaman/engineer + icon_state = "plasmamanEngineer_helmet0" + base_state = "plasmamanEngineer_helmet" + + +//SERVICE + +/obj/item/clothing/suit/space/eva/plasmaman/botanist + icon_state = "plasmamanBotanist_suit" + +/obj/item/clothing/head/helmet/space/eva/plasmaman/botanist + icon_state = "plasmamanBotanist_helmet0" + base_state = "plasmamanBotanist_helmet" + +/obj/item/clothing/suit/space/eva/plasmaman/chaplain + icon_state = "plasmamanChaplain_suit" + +/obj/item/clothing/head/helmet/space/eva/plasmaman/chaplain + icon_state = "plasmamanChaplain_helmet0" + base_state = "plasmamanChaplain_helmet" + +/obj/item/clothing/suit/space/eva/plasmaman/service + icon_state = "plasmamanService_suit" + +/obj/item/clothing/head/helmet/space/eva/plasmaman/service + icon_state = "plasmamanService_helmet0" + base_state = "plasmamanService_helmet" + +/obj/item/clothing/suit/space/eva/plasmaman/janitor + icon_state = "plasmamanJanitor_suit" + +/obj/item/clothing/head/helmet/space/eva/plasmaman/janitor + icon_state = "plasmamanJanitor_helmet0" + base_state = "plasmamanJanitor_helmet" + + +//CARGO + +/obj/item/clothing/suit/space/eva/plasmaman/cargo + icon_state = "plasmamanCargo_suit" + +/obj/item/clothing/head/helmet/space/eva/plasmaman/cargo + icon_state = "plasmamanCargo_helmet0" + base_state = "plasmamanCargo_helmet" + +/obj/item/clothing/suit/space/eva/plasmaman/miner + icon_state = "plasmamanMiner_suit" + +/obj/item/clothing/head/helmet/space/eva/plasmaman/miner + icon_state = "plasmamanMiner_helmet0" + base_state = "plasmamanMiner_helmet" + + +// MEDSCI + +/obj/item/clothing/suit/space/eva/plasmaman/medical + icon_state = "plasmamanMedical_suit" + +/obj/item/clothing/head/helmet/space/eva/plasmaman/medical + icon_state = "plasmamanMedical_helmet0" + base_state = "plasmamanMedical_helmet" + +/obj/item/clothing/suit/space/eva/plasmaman/science + icon_state = "plasmamanScience_suit" + +/obj/item/clothing/head/helmet/space/eva/plasmaman/science + icon_state = "plasmamanScience_helmet0" + base_state = "plasmamanScience_helmet" + + +//SECURITY + +/obj/item/clothing/suit/space/eva/plasmaman/security + icon_state = "plasmamanSecurity_suit" + +/obj/item/clothing/head/helmet/space/eva/plasmaman/security + icon_state = "plasmamanSecurity_helmet0" + base_state = "plasmamanSecurity_helmet" \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/rig.dm b/code/modules/clothing/spacesuits/rig.dm index ce7e86c94ca..06b61fc94e9 100644 --- a/code/modules/clothing/spacesuits/rig.dm +++ b/code/modules/clothing/spacesuits/rig.dm @@ -112,7 +112,7 @@ //TODO: Species check, skull damage for forcing an unfitting helmet on? helmet.loc = H H.equip_to_slot(helmet, slot_head) - helmet.canremove = 0 + helmet.flags |= NODROP if(attached_boots && boots) if(H.shoes) @@ -121,7 +121,7 @@ M << "Your suit's boots deploy with a hiss." boots.loc = H H.equip_to_slot(boots, slot_shoes) - boots.canremove = 0 + boots.flags |= NODROP /obj/item/clothing/suit/space/rig/dropped() ..() @@ -132,16 +132,16 @@ H = helmet.loc if(istype(H)) if(helmet && H.head == helmet) - helmet.canremove = 1 - H.drop_from_inventory(helmet) + helmet.flags &= ~NODROP + H.unEquip(helmet) helmet.loc = src if(boots) H = boots.loc if(istype(H)) if(boots && H.shoes == boots) - boots.canremove = 1 - H.drop_from_inventory(boots) + boots.flags &= ~NODROP + H.unEquip(boots) boots.loc = src /* @@ -206,8 +206,8 @@ if(H.wear_suit != src) return if(H.head == helmet) - helmet.canremove = 1 - H.drop_from_inventory(helmet) + helmet.flags &= ~NODROP + H.unEquip(helmet) helmet.loc = src H << "\blue You retract your hardsuit helmet." else @@ -218,10 +218,11 @@ helmet.loc = H helmet.pickup(H) H.equip_to_slot(helmet, slot_head) - helmet.canremove = 0 + helmet.flags |= NODROP H << "\blue You deploy your hardsuit helmet, sealing you off from the world." + H.update_inv_head() -/obj/item/clothing/suit/space/rig/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/clothing/suit/space/rig/attackby(obj/item/W as obj, mob/user as mob, params) if(!istype(user,/mob/living)) return @@ -365,44 +366,90 @@ //Syndicate rig /obj/item/clothing/head/helmet/space/rig/syndi name = "blood-red hardsuit helmet" - desc = "An advanced helmet designed for work in special operations. Property of Gorlex Marauders." - icon_state = "rig0-syndie" + desc = "A dual-mode advanced helmet designed for work in special operations. It is in travel mode. Property of Gorlex Marauders." + icon_state = "hardsuit1-syndi" item_state = "syndie_helm" - _color = "syndie" + _color = "syndi" armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 50) - siemens_coefficient = 0.6 - var/obj/machinery/camera/camera - species_restricted = list("exclude","Unathi","Tajaran","Skrell","Vox") + on = 1 + flags = HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPSPRESSUREDMAGE | THICKMATERIAL + action_button_name = "Toggle Helmet Mode" + icon_action_button = "Action_hardsuit1-syndi" + species_restricted = null + sprite_sheets = null +/obj/item/clothing/head/helmet/space/rig/syndi/update_icon() + icon_state = "hardsuit[on]-[_color]" /obj/item/clothing/head/helmet/space/rig/syndi/attack_self(mob/user) - if(camera) - ..(user) + if(!isturf(user.loc)) + user << "You cannot toggle your helmet while in this [user.loc]" //To prevent some lighting anomalities. + return + on = !on + if(on) + user << "You switch your helmet to travel mode." + name = "blood-red hardsuit helmet" + desc = "A dual-mode advanced helmet designed for work in special operations. It is in travel mode. Property of Gorlex Marauders." + flags = HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPSPRESSUREDMAGE | THICKMATERIAL + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE + cold_protection = HEAD + user.AddLuminosity(brightness_on) else - camera = new /obj/machinery/camera(src) - camera.network = list("NukeOps") - cameranet.removeCamera(camera) - camera.c_tag = user.name - user << "\blue User scanned as [camera.c_tag]. Camera activated." + user << "You switch your helmet to combat mode." + name = "blood-red hardsuit helmet (combat)" + desc = "A dual-mode advanced helmet designed for work in special operations. It is in combat mode. Property of Gorlex Marauders." + flags = BLOCKHAIR + flags_inv = HIDEEARS + cold_protection = null + user.AddLuminosity(-brightness_on) -/obj/item/clothing/head/helmet/space/rig/syndi/examine() - ..() - if(get_dist(usr,src) <= 1) - usr << "This helmet has a built-in camera. It's [camera ? "" : "in"]active." + update_icon() + playsound(src.loc, 'sound/mecha/mechmove03.ogg', 50, 1) + user.update_inv_head() /obj/item/clothing/suit/space/rig/syndi - icon_state = "rig-syndie" name = "blood-red hardsuit" - desc = "An advanced suit that protects against injuries during special operations. Property of Gorlex Marauders." + desc = "A dual-mode advanced hardsuit designed for work in special operations. It is in travel mode. Property of Gorlex Marauders." + icon_state = "hardsuit1-syndi" item_state = "syndie_hardsuit" + _color = "syndi" slowdown = 1 w_class = 3 + var/on = 1 + action_button_name = "Toggle Hardsuit Mode" + icon_action_button = "Action_hardsuit1-syndi" armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 50) - allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box/magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs,/obj/item/weapon/tank) - siemens_coefficient = 0.6 - species_restricted = list("exclude","Unathi","Tajaran","Skrell","Vox") + allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank) + species_restricted = null sprite_sheets = null +/obj/item/clothing/suit/space/rig/syndi/update_icon() + icon_state = "hardsuit[on]-[_color]" + +/obj/item/clothing/suit/space/rig/syndi/attack_self(mob/user) + on = !on + if(on) + user << "You switch your hardsuit to travel mode." + name = "blood-red hardsuit helmet" + desc = "A dual-mode advanced hardsuit designed for work in special operations. It is in travel mode. Property of Gorlex Marauders." + slowdown = 1 + flags = STOPSPRESSUREDMAGE | THICKMATERIAL + flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS + else + user << "You switch your hardsuit to combat mode." + name = "blood-red hardsuit helmet (combat)" + desc = "A dual-mode advanced hardsuit designed for work in special operations. It is in combat mode. Property of Gorlex Marauders." + slowdown = 0 + flags = BLOCKHAIR + flags_inv = null + cold_protection = null + + update_icon() + playsound(src.loc, 'sound/mecha/mechmove03.ogg', 50, 1) + user.update_inv_wear_suit() + user.update_inv_w_uniform() + //Wizard Rig /obj/item/clothing/head/helmet/space/rig/wizard name = "gem-encrusted hardsuit helmet" @@ -469,7 +516,7 @@ desc = "A special suit that protects against hazardous, low pressure environments. Has an additional layer of armor." item_state = "sec_hardsuit" armor = list(melee = 30, bullet = 15, laser = 30, energy = 10, bomb = 10, bio = 100, rad = 50) - allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/melee/baton,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/handcuffs) + allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/melee/baton,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/restraints/handcuffs) siemens_coefficient = 0.7 @@ -508,5 +555,5 @@ name = "singuloth knight's armor" desc = "This is a ceremonial armor from the chapter of the Singuloth Knights. It's made of pure forged adamantium." item_state = "singuloth_hardsuit" - flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE + flags = STOPSPRESSUREDMAGE armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 25, bio = 100, rad = 100) diff --git a/code/modules/clothing/spacesuits/syndi.dm b/code/modules/clothing/spacesuits/syndi.dm index a7797fcdc48..894e9ed1cf1 100644 --- a/code/modules/clothing/spacesuits/syndi.dm +++ b/code/modules/clothing/spacesuits/syndi.dm @@ -14,7 +14,7 @@ item_state = "space_suit_syndicate" desc = "Has a tag on it: Totally not property of of a hostile corporation, honest!" w_class = 3 - allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs,/obj/item/weapon/tank) + allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank) slowdown = 1 armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) siemens_coefficient = 0.8 diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index d92dabb8535..627b5e8a0b9 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -1,8 +1,7 @@ /obj/item/clothing/suit/armor - allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/device/flashlight/seclite,/obj/item/weapon/melee/telebaton) + allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/device/flashlight/seclite,/obj/item/weapon/melee/telebaton) body_parts_covered = UPPER_TORSO|LOWER_TORSO - flags = FPRINT | TABLEPASS cold_protection = UPPER_TORSO|LOWER_TORSO min_cold_protection_temperature = ARMOR_MIN_COLD_PROTECTION_TEMPERATURE heat_protection = UPPER_TORSO|LOWER_TORSO @@ -16,8 +15,15 @@ icon_state = "armor" item_state = "armor" blood_overlay_type = "armor" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0) + +/obj/item/clothing/suit/armor/vest/jacket + name = "military jacket" + desc = "An old military jacket, it has armoring." + icon_state = "militaryjacket" + item_state = "militaryjacket" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS /obj/item/clothing/suit/armor/vest/combat name = "combat vest" @@ -25,7 +31,7 @@ icon_state = "armor-combat" item_state = "bulletproof" blood_overlay_type = "armor" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0) /obj/item/clothing/suit/armor/vest/security @@ -146,8 +152,8 @@ icon_state = "detective-armor" item_state = "armor" blood_overlay_type = "armor" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL - allowed = list(/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/device/flashlight,/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter,/obj/item/device/detective_scanner,/obj/item/device/taperecorder) + flags = ONESIZEFITSALL + allowed = list(/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/device/flashlight,/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter,/obj/item/device/detective_scanner,/obj/item/device/taperecorder) //Reactive armor @@ -160,7 +166,6 @@ item_state = "reactiveoff" blood_overlay_type = "armor" slowdown = 1 - flags = FPRINT | TABLEPASS icon_action_button = "reactiveoff" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) @@ -199,7 +204,8 @@ item_state = "centcom" w_class = 4//bulky item body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS - allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank/emergency_oxygen) + allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank/emergency_oxygen) + flags = THICKMATERIAL flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE @@ -212,6 +218,7 @@ item_state = "swat_suit" w_class = 4//bulky item gas_transfer_coefficient = 0.90 + flags = THICKMATERIAL body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS slowdown = 3 flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT @@ -220,6 +227,9 @@ /obj/item/clothing/suit/armor/tdome body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + flags = THICKMATERIAL + cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS + heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS /obj/item/clothing/suit/armor/tdome/red name = "Thunderdome suit (red)" diff --git a/code/modules/clothing/suits/bio.dm b/code/modules/clothing/suits/bio.dm index 18025e077e4..6764838430b 100644 --- a/code/modules/clothing/suits/bio.dm +++ b/code/modules/clothing/suits/bio.dm @@ -4,7 +4,7 @@ icon_state = "bio" desc = "A hood that protects the head and face from biological comtaminants." permeability_coefficient = 0.01 - flags = FPRINT|TABLEPASS|HEADCOVERSEYES|HEADCOVERSMOUTH|BLOCKHAIR + flags = HEADCOVERSEYES | HEADCOVERSMOUTH | BLOCKHAIR | THICKMATERIAL armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 20) flags_inv = HIDEMASK|HIDEEARS|HIDEEYES siemens_coefficient = 0.9 @@ -18,7 +18,7 @@ w_class = 4//bulky item gas_transfer_coefficient = 0.01 permeability_coefficient = 0.01 - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL | THICKMATERIAL body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS slowdown = 1.0 allowed = list(/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/pen,/obj/item/device/flashlight/pen) diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index 7f4b11ef8b2..8672b135934 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -48,7 +48,7 @@ item_state = "bio_suit" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS flags_inv = HIDEJUMPSUIT - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL allowed = list(/obj/item/weapon/disk, /obj/item/weapon/stamp, /obj/item/weapon/reagent_containers/food/drinks/flask, /obj/item/weapon/melee, /obj/item/weapon/storage/lockbox/medal, /obj/item/device/flash, /obj/item/weapon/storage/box/matches, /obj/item/weapon/lighter, /obj/item/clothing/mask/cigarette, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/tank/emergency_oxygen) species_fit = list("Vox") sprite_sheets = list( @@ -132,11 +132,11 @@ item_state = "det_suit" blood_overlay_type = "coat" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS - allowed = list(/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/device/flashlight,/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter,/obj/item/device/detective_scanner,/obj/item/device/taperecorder) + allowed = list(/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/device/flashlight,/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter,/obj/item/device/detective_scanner,/obj/item/device/taperecorder) armor = list(melee = 50, bullet = 10, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0) cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/suit.dmi' @@ -148,7 +148,7 @@ desc = "A forensics technician jacket." item_state = "det_suit" body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS - allowed = list(/obj/item/weapon/tank/emergency_oxygen, /obj/item/device/flashlight,/obj/item/weapon/gun/energy,/obj/item/weapon/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/device/detective_scanner,/obj/item/device/taperecorder) + allowed = list(/obj/item/weapon/tank/emergency_oxygen, /obj/item/device/flashlight,/obj/item/weapon/gun/energy,/obj/item/weapon/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/device/detective_scanner,/obj/item/device/taperecorder) armor = list(melee = 10, bullet = 10, laser = 15, energy = 10, bomb = 0, bio = 0, rad = 0) /obj/item/clothing/suit/storage/forensics/red @@ -175,6 +175,14 @@ ) //Lawyer +/obj/item/clothing/suit/storage/lawyer/blackjacket + name = "Black Suit Jacket" + desc = "A snappy dress jacket." + icon_state = "suitjacket_black_open" + item_state = "suitjacket_black_open" + blood_overlay_type = "coat" + body_parts_covered = UPPER_TORSO|ARMS + /obj/item/clothing/suit/storage/lawyer/bluejacket name = "Blue Suit Jacket" desc = "A snappy dress jacket." diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index f2c6ab9eb88..1655618eb8f 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -36,14 +36,12 @@ desc = "Yarr." icon_state = "pirate_old" item_state = "pirate_old" - flags = FPRINT | TABLEPASS /obj/item/clothing/suit/pirate_black name = "black pirate coat" desc = "Yarr." icon_state = "pirate" item_state = "pirate" - flags = FPRINT | TABLEPASS /obj/item/clothing/suit/hgpirate @@ -51,7 +49,6 @@ desc = "Yarr." icon_state = "hgpirate" item_state = "hgpirate" - flags = FPRINT | TABLEPASS flags_inv = HIDEJUMPSUIT @@ -60,7 +57,7 @@ desc = "Suit for a cyborg costume." icon_state = "death" item_state = "death" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT fire_resist = T0C+5200 flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT @@ -70,7 +67,6 @@ desc = "A Nazi great coat" icon_state = "nazi" item_state = "nazi" - flags = FPRINT | TABLEPASS /obj/item/clothing/suit/johnny_coat @@ -78,7 +74,6 @@ desc = "Johnny~~" icon_state = "johnny" item_state = "johnny" - flags = FPRINT | TABLEPASS /obj/item/clothing/suit/justice @@ -86,7 +81,6 @@ desc = "this pretty much looks ridiculous" icon_state = "justice" item_state = "justice" - flags = FPRINT | TABLEPASS flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT @@ -95,7 +89,6 @@ desc = "This robe commands authority." icon_state = "judge" item_state = "judge" - flags = FPRINT | TABLEPASS body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS allowed = list(/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/spacecash) flags_inv = HIDEJUMPSUIT @@ -124,7 +117,6 @@ item_state = "syndicate-black-red" desc = "A plastic replica of the syndicate space suit, you'll look just like a real murderous syndicate agent in this! This is a toy, it is not made for use in space!" w_class = 3 - flags = FPRINT | TABLEPASS allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/toy) flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT @@ -215,7 +207,7 @@ desc = "Forced to live on your shameful acting as a fake Mexican, you and your poncho have grown inseperable. Literally." icon_state = "ponchoshame" item_state = "ponchoshame" - canremove = 0 + flags = NODROP /* * Misc @@ -228,7 +220,7 @@ item_state = "straight_jacket" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/suit/ianshirt name = "worn shirt" @@ -282,21 +274,18 @@ desc = "A long, thick black leather coat." icon_state = "leathercoat" item_state = "leathercoat" - flags = FPRINT | TABLEPASS /obj/item/clothing/suit/browncoat name = "brown leather coat" desc = "A long, brown leather coat." icon_state = "browncoat" item_state = "browncoat" - flags = FPRINT | TABLEPASS /obj/item/clothing/suit/neocoat name = "black coat" desc = "A flowing, black coat." icon_state = "neocoat" item_state = "neocoat" - flags = FPRINT | TABLEPASS /obj/item/clothing/suit/browntrenchcoat name = "brown trench coat" @@ -318,7 +307,6 @@ desc = "A cream coloured, genteel suit." icon_state = "creamsuit" item_state = "creamsuit" - flags = FPRINT | TABLEPASS //stripper @@ -412,7 +400,7 @@ w_class = 4//bulky item gas_transfer_coefficient = 0.01 permeability_coefficient = 0.01 - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS allowed = list(/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/pen,/obj/item/device/flashlight/pen) armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 20) @@ -425,7 +413,7 @@ icon_state = "mercy_hood" item_state = "mercy_hood" permeability_coefficient = 0.01 - flags = FPRINT|TABLEPASS|HEADCOVERSEYES|HEADCOVERSMOUTH|BLOCKHAIR + flags = HEADCOVERSEYES | HEADCOVERSMOUTH | BLOCKHAIR armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 20) flags_inv = HIDEMASK|HIDEEARS|HIDEEYES siemens_coefficient = 0.9 @@ -456,3 +444,37 @@ desc = "An overcoat for the clown soldier, to keep him warm during those cold winter nights on the front." icon_state = "soldiersuit" item_state = "soldiersuit" + +/obj/item/clothing/suit/toggle/owlwings + name = "owl cloak" + desc = "A soft brown cloak made of synthetic feathers. Soft to the touch, stylish, and a 2 meter wing span that will drive the ladies mad." + icon_state = "owl_wings" + item_state = "owl_wings" + body_parts_covered = ARMS + armor = list(melee = 5, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) + allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/device/flashlight/seclite) + action_button_name = "Toggle Owl Wings" + icon_action_button = "action_wings" + flags = NODROP + +/obj/item/clothing/suit/toggle/owlwings/griffinwings + name = "griffon cloak" + desc = "A plush white cloak made of synthetic feathers. Soft to the touch, stylish, and a 2 meter wing span that will drive your captives mad." + icon_state = "griffin_wings" + item_state = "griffin_wings" + +/obj/item/clothing/suit/toggle/attack_self() + if(icon_state == initial(icon_state)) + icon_state = icon_state + "_t" + item_state = icon_state + "_t" + else + icon_state = initial(icon_state) + item_state = initial(item_state) + usr.update_inv_wear_suit() + +/obj/item/clothing/suit/lordadmiral + name = "Lord Admiral's Coat" + desc = "You'll be the Ruler of the King's Navy in no time." + icon_state = "lordadmiral" + item_state = "lordadmiral" + allowed = list (/obj/item/weapon/gun) \ No newline at end of file diff --git a/code/modules/clothing/suits/storage.dm b/code/modules/clothing/suits/storage.dm new file mode 100644 index 00000000000..12c21e2a70e --- /dev/null +++ b/code/modules/clothing/suits/storage.dm @@ -0,0 +1,43 @@ +/obj/item/clothing/suit/storage + var/obj/item/weapon/storage/internal/pockets + +/obj/item/clothing/suit/storage/New() + ..() + pockets = new/obj/item/weapon/storage/internal(src) + pockets.storage_slots = 2 //two slots + pockets.max_w_class = 2 //fit only pocket sized items + pockets.max_combined_w_class = 4 + +/obj/item/clothing/suit/storage/attack_hand(mob/user as mob) + if (pockets.handle_attack_hand(user)) + ..(user) + +/obj/item/clothing/suit/storage/MouseDrop(obj/over_object as obj) + if (pockets.handle_mousedrop(usr, over_object)) + ..(over_object) + +/obj/item/clothing/suit/storage/attackby(obj/item/W as obj, mob/user as mob, params) + ..() + pockets.attackby(W, user, params) + +/obj/item/clothing/suit/storage/emp_act(severity) + pockets.emp_act(severity) + ..() + +/obj/item/clothing/suit/storage/hear_talk(mob/M, var/msg) + pockets.hear_talk(M, msg) + ..() + +/obj/item/clothing/suit/storage/proc/return_inv() + + var/list/L = list( ) + + L += src.contents + + for(var/obj/item/weapon/storage/S in src) + L += S.return_inv() + for(var/obj/item/weapon/gift/G in src) + L += G.gift + if (istype(G.gift, /obj/item/weapon/storage)) + L += G.gift:return_inv() + return L \ No newline at end of file diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm index 4896840ab1e..08d3757a95f 100644 --- a/code/modules/clothing/suits/utility.dm +++ b/code/modules/clothing/suits/utility.dm @@ -21,7 +21,7 @@ allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/extinguisher) slowdown = 1.0 flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL - flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE + flags = STOPSPRESSUREDMAGE | THICKMATERIAL heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS @@ -55,7 +55,7 @@ name = "bomb hood" desc = "Use in case of bomb." icon_state = "bombsuit" - flags = FPRINT|TABLEPASS|HEADCOVERSEYES|HEADCOVERSMOUTH|BLOCKHAIR + flags = HEADCOVERSEYES | HEADCOVERSMOUTH | BLOCKHAIR | THICKMATERIAL armor = list(melee = 40, bullet = 0, laser = 20,energy = 10, bomb = 100, bio = 0, rad = 0) flags_inv = HIDEMASK|HIDEEARS|HIDEEYES cold_protection = HEAD @@ -74,7 +74,7 @@ w_class = 4//bulky item gas_transfer_coefficient = 0.01 permeability_coefficient = 0.01 - flags = FPRINT | TABLEPASS + flags = THICKMATERIAL body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS slowdown = 2 armor = list(melee = 40, bullet = 0, laser = 20,energy = 10, bomb = 100, bio = 0, rad = 0) @@ -94,7 +94,7 @@ /obj/item/clothing/suit/bomb_suit/security icon_state = "bombsuitsec" item_state = "bombsuitsec" - allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs) + allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs) /* * Radiation protection @@ -103,7 +103,7 @@ name = "Radiation Hood" icon_state = "rad" desc = "A hood with radiation protective properties. Label: Made with lead, do not eat insulation" - flags = FPRINT|TABLEPASS|HEADCOVERSEYES|HEADCOVERSMOUTH|BLOCKHAIR + flags = HEADCOVERSEYES|HEADCOVERSMOUTH|BLOCKHAIR|THICKMATERIAL armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 60, rad = 100) loose = 8 @@ -115,6 +115,7 @@ w_class = 4//bulky item gas_transfer_coefficient = 0.90 permeability_coefficient = 0.50 + flags = THICKMATERIAL body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen) slowdown = 1.5 diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm new file mode 100644 index 00000000000..ee6800f4c18 --- /dev/null +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -0,0 +1,319 @@ +/obj/item/clothing/accessory + name = "tie" + desc = "A neosilk clip-on tie." + icon = 'icons/obj/clothing/ties.dmi' + icon_state = "bluetie" + item_state = "" //no inhands + _color = "bluetie" + slot_flags = SLOT_TIE + w_class = 2.0 + var/slot = "decor" + var/obj/item/clothing/under/has_suit = null //the suit the tie may be attached to + var/image/inv_overlay = null //overlay used when attached to clothing. + +/obj/item/clothing/accessory/New() + ..() + inv_overlay = image("icon" = 'icons/obj/clothing/ties_overlay.dmi', "icon_state" = "[_color? "[_color]" : "[icon_state]"]") + +//when user attached an accessory to S +/obj/item/clothing/accessory/proc/on_attached(obj/item/clothing/under/S, mob/user as mob) + if(!istype(S)) + return + has_suit = S + loc = has_suit + has_suit.overlays += inv_overlay + + user << "You attach [src] to [has_suit]." + src.add_fingerprint(user) + +/obj/item/clothing/accessory/proc/on_removed(mob/user as mob) + if(!has_suit) + return + has_suit.overlays -= inv_overlay + has_suit = null + usr.put_in_hands(src) + src.add_fingerprint(user) + +//default attackby behaviour +/obj/item/clothing/accessory/attackby(obj/item/I, mob/user, params) + ..() + +//default attack_hand behaviour +/obj/item/clothing/accessory/attack_hand(mob/user as mob) + if(has_suit) + return //we aren't an object on the ground so don't call parent + ..() + +/obj/item/clothing/accessory/blue + name = "blue tie" + icon_state = "bluetie" + _color = "bluetie" + +/obj/item/clothing/accessory/red + name = "red tie" + icon_state = "redtie" + _color = "redtie" + +/obj/item/clothing/accessory/black + name = "black tie" + icon_state = "blacktie" + _color = "blacktie" + +/obj/item/clothing/accessory/horrible + name = "horrible tie" + desc = "A neosilk clip-on tie. This one is disgusting." + icon_state = "horribletie" + _color = "horribletie" + +/obj/item/clothing/accessory/waistcoat // No overlay + name = "waistcoat" + desc = "For some classy, murderous fun." + icon_state = "waistcoat" + item_state = "waistcoat" + _color = "waistcoat" + +/obj/item/clothing/accessory/stethoscope + name = "stethoscope" + desc = "An outdated medical apparatus for listening to the sounds of the human body. It also makes you look like you know what you're doing." + icon_state = "stethoscope" + _color = "stethoscope" + +/obj/item/clothing/accessory/stethoscope/attack(mob/living/carbon/human/M, mob/living/user) + if(ishuman(M) && isliving(user)) + if(user.a_intent == "help") + var/body_part = parse_zone(user.zone_sel.selecting) + if(body_part) + var/their = "their" + switch(M.gender) + if(MALE) their = "his" + if(FEMALE) their = "her" + + var/sound = "pulse" + var/sound_strength + + if(M.stat == DEAD || (M.status_flags&FAKEDEATH)) + sound_strength = "cannot hear" + sound = "anything" + else + sound_strength = "hear a weak" + switch(body_part) + if("chest") + if(M.oxyloss < 50) + sound_strength = "hear a healthy" + sound = "pulse and respiration" + if("eyes","mouth") + sound_strength = "cannot hear" + sound = "anything" + else + sound_strength = "hear a weak" + + user.visible_message("[user] places [src] against [M]'s [body_part] and listens attentively.", "You place [src] against [their] [body_part]. You [sound_strength] [sound].") + return + return ..(M,user) + + +//Medals +/obj/item/clothing/accessory/medal + name = "bronze medal" + desc = "A bronze medal." + icon_state = "bronze" + _color = "bronze" + +/obj/item/clothing/accessory/medal/conduct + name = "distinguished conduct medal" + desc = "A bronze medal awarded for distinguished conduct. Whilst a great honor, this is most basic award given by Nanotrasen. It is often awarded by a captain to a member of his crew." + +/obj/item/clothing/accessory/medal/bronze_heart + name = "bronze heart medal" + desc = "A bronze heart-shaped medal awarded for sacrifice. It is often awarded posthumously or for severe injury in the line of duty." + icon_state = "bronze_heart" + +/obj/item/clothing/accessory/medal/nobel_science + name = "nobel sciences award" + desc = "A bronze medal which represents significant contributions to the field of science or engineering." + +/obj/item/clothing/accessory/medal/silver + name = "silver medal" + desc = "A silver medal." + icon_state = "silver" + _color = "silver" + +/obj/item/clothing/accessory/medal/silver/valor + name = "medal of valor" + desc = "A silver medal awarded for acts of exceptional valor." + +/obj/item/clothing/accessory/medal/silver/security + name = "robust security award" + desc = "An award for distinguished combat and sacrifice in defence of Nanotrasen's commercial interests. Often awarded to security staff." + +/obj/item/clothing/accessory/medal/gold + name = "gold medal" + desc = "A prestigious golden medal." + icon_state = "gold" + _color = "gold" + +/obj/item/clothing/accessory/medal/gold/captain + name = "medal of captaincy" + desc = "A golden medal awarded exclusively to those promoted to the rank of captain. It signifies the codified responsibilities of a captain to Nanotrasen, and their undisputable authority over their crew." + +/obj/item/clothing/accessory/medal/gold/heroism + name = "medal of exceptional heroism" + desc = "An extremely rare golden medal awarded only by CentComm. To recieve such a medal is the highest honor and as such, very few exist. This medal is almost never awarded to anybody but commanders." + +/* + Holobadges are worn on the belt or neck, and can be used to show that the holder is an authorized + Security agent - the user details can be imprinted on the badge with a Security-access ID card, + or they can be emagged to accept any ID for use in disguises. +*/ + +/obj/item/clothing/accessory/holobadge + name = "holobadge" + desc = "This glowing blue badge marks the holder as THE LAW." + icon_state = "holobadge" + _color = "holobadge" + slot_flags = SLOT_BELT | SLOT_TIE + + var/emagged = 0 //Emagging removes Sec check. + var/stored_name = null + +/obj/item/clothing/accessory/holobadge/cord + icon_state = "holobadge-cord" + _color = "holobadge-cord" + slot_flags = SLOT_MASK | SLOT_TIE + +/obj/item/clothing/accessory/holobadge/attack_self(mob/user as mob) + if(!stored_name) + user << "Waving around a badge before swiping an ID would be pretty pointless." + return + if(isliving(user)) + user.visible_message("\red [user] displays their NanoTrasen Internal Security Legal Authorization Badge.\nIt reads: [stored_name], NT Security.","\red You display your NanoTrasen Internal Security Legal Authorization Badge.\nIt reads: [stored_name], NT Security.") + +/obj/item/clothing/accessory/holobadge/attackby(var/obj/item/O as obj, var/mob/user as mob, params) + if(istype(O, /obj/item/weapon/card/id) || istype(O, /obj/item/device/pda)) + + var/obj/item/weapon/card/id/id_card = null + + if(istype(O, /obj/item/weapon/card/id)) + id_card = O + else + var/obj/item/device/pda/pda = O + id_card = pda.id + + if(access_security in id_card.access || emagged) + user << "You imprint your ID details onto the badge." + stored_name = id_card.registered_name + name = "holobadge ([stored_name])" + desc = "This glowing blue badge marks [stored_name] as THE LAW." + else + user << "[src] rejects your insufficient access rights." + return + ..() + +/obj/item/clothing/accessory/holobadge/emag_act(user as mob) + if (emagged) + user << "\red [src] is already cracked." + return + else + emagged = 1 + user << "\red You swipe the card and crack the holobadge security checks." + return + +/obj/item/clothing/accessory/holobadge/attack(mob/living/carbon/human/M, mob/living/user) + if(isliving(user)) + user.visible_message("\red [user] invades [M]'s personal space, thrusting [src] into their face insistently.","\red You invade [M]'s personal space, thrusting [src] into their face insistently. You are the law.") + +/obj/item/weapon/storage/box/holobadge + name = "holobadge box" + desc = "A box claiming to contain holobadges." + New() + new /obj/item/clothing/accessory/holobadge(src) + new /obj/item/clothing/accessory/holobadge(src) + new /obj/item/clothing/accessory/holobadge(src) + new /obj/item/clothing/accessory/holobadge(src) + new /obj/item/clothing/accessory/holobadge/cord(src) + new /obj/item/clothing/accessory/holobadge/cord(src) + ..() + return + + +/////////// +//SCARVES// +/////////// + +/obj/item/clothing/accessory/scarf // No overlay + name = "scarf" + desc = "A stylish scarf. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their necks." + +/obj/item/clothing/accessory/scarf/red + name = "red scarf" + icon_state = "redscarf" + _color = "redscarf" + +/obj/item/clothing/accessory/scarf/green + name = "green scarf" + icon_state = "greenscarf" + _color = "greenscarf" + +/obj/item/clothing/accessory/scarf/darkblue + name = "dark blue scarf" + icon_state = "darkbluescarf" + _color = "darkbluescarf" + +/obj/item/clothing/accessory/scarf/purple + name = "purple scarf" + icon_state = "purplescarf" + _color = "purplescarf" + +/obj/item/clothing/accessory/scarf/yellow + name = "yellow scarf" + icon_state = "yellowscarf" + _color = "yellowscarf" + +/obj/item/clothing/accessory/scarf/orange + name = "orange scarf" + icon_state = "orangescarf" + _color = "orangescarf" + +/obj/item/clothing/accessory/scarf/lightblue + name = "light blue scarf" + icon_state = "lightbluescarf" + _color = "lightbluescarf" + +/obj/item/clothing/accessory/scarf/white + name = "white scarf" + icon_state = "whitescarf" + _color = "whitescarf" + +/obj/item/clothing/accessory/scarf/black + name = "black scarf" + icon_state = "blackscarf" + _color = "blackscarf" + +/obj/item/clothing/accessory/scarf/zebra + name = "zebra scarf" + icon_state = "zebrascarf" + _color = "zebrascarf" + +/obj/item/clothing/accessory/scarf/christmas + name = "christmas scarf" + icon_state = "christmasscarf" + _color = "christmasscarf" + +//The three following scarves don't have the scarf subtype +//This is because Ian can equip anything from that subtype +//However, these 3 don't have corgi versions of their sprites +/obj/item/clothing/accessory/stripedredscarf + name = "striped red scarf" + icon_state = "stripedredscarf" + _color = "stripedredscarf" + +/obj/item/clothing/accessory/stripedgreenscarf + name = "striped green scarf" + icon_state = "stripedgreenscarf" + _color = "stripedgreenscarf" + +/obj/item/clothing/accessory/stripedbluescarf + name = "striped blue scarf" + icon_state = "stripedbluescarf" + _color = "stripedbluescarf" + diff --git a/code/modules/clothing/under/accessories/armband.dm b/code/modules/clothing/under/accessories/armband.dm new file mode 100644 index 00000000000..8c4dd79ffe8 --- /dev/null +++ b/code/modules/clothing/under/accessories/armband.dm @@ -0,0 +1,42 @@ +/obj/item/clothing/accessory/armband + name = "red armband" + desc = "A fancy red armband!" + icon_state = "red" + _color = "red" + slot = "armband" + +/obj/item/clothing/accessory/armband/cargo + name = "cargo armband" + desc = "An armband, worn by the crew to display which department they're assigned to. This one is brown." + icon_state = "cargo" + _color = "cargo" + +/obj/item/clothing/accessory/armband/engine + name = "engineering armband" + desc = "An armband, worn by the crew to display which department they're assigned to. This one is orange with a reflective strip!" + icon_state = "engie" + _color = "engie" + +/obj/item/clothing/accessory/armband/science + name = "science armband" + desc = "An armband, worn by the crew to display which department they're assigned to. This one is purple." + icon_state = "rnd" + _color = "rnd" + +/obj/item/clothing/accessory/armband/hydro + name = "hydroponics armband" + desc = "An armband, worn by the crew to display which department they're assigned to. This one is green and blue." + icon_state = "hydro" + _color = "hydro" + +/obj/item/clothing/accessory/armband/med + name = "medical armband" + desc = "An armband, worn by the crew to display which department they're assigned to. This one is white." + icon_state = "med" + _color = "med" + +/obj/item/clothing/accessory/armband/medgreen + name = "EMT armband" + desc = "An armband, worn by the crew to display which department they're assigned to. This one is white and green." + icon_state = "medgreen" + _color = "medgreen" diff --git a/code/modules/clothing/under/accessories/holster.dm b/code/modules/clothing/under/accessories/holster.dm new file mode 100644 index 00000000000..3d61a789742 --- /dev/null +++ b/code/modules/clothing/under/accessories/holster.dm @@ -0,0 +1,135 @@ +/obj/item/clothing/accessory/holster + name = "shoulder holster" + desc = "A handgun holster." + icon_state = "holster" + _color = "holster" + slot = "utility" + var/holster_allow = /obj/item/weapon/gun + var/obj/item/weapon/gun/holstered = null + icon_action_button = "action_holster" + w_class = 3.0 // so it doesn't fit in pockets + +//subtypes can override this to specify what can be holstered +/obj/item/clothing/accessory/holster/proc/can_holster(obj/item/weapon/gun/W) + if(!W.isHandgun()) + return 0 + else if(!istype(W,holster_allow)) + return 0 + else + return 1 + +/obj/item/clothing/accessory/holster/attack_self() + var/holsteritem = usr.get_active_hand() + if(!holstered) + holster(holsteritem, usr) + else + unholster(usr) + +/obj/item/clothing/accessory/holster/proc/holster(obj/item/I, mob/user as mob) + if(holstered) + user << "There is already a [holstered] holstered here!" + return + + if (!istype(I, /obj/item/weapon/gun)) + user << "Only guns can be holstered!" + return + + var/obj/item/weapon/gun/W = I + if (!can_holster(W)) + user << "This [W] won't fit in the [src]!" + return + + holstered = W + user.unEquip(holstered) + holstered.loc = src + holstered.add_fingerprint(user) + user.visible_message("[user] holsters the [holstered].", "You holster the [holstered].") + +/obj/item/clothing/accessory/holster/proc/unholster(mob/user as mob) + if(!holstered) + return + + if(istype(user.get_active_hand(),/obj) && istype(user.get_inactive_hand(),/obj)) + user << "You need an empty hand to draw the [holstered]!" + else + if(user.a_intent == "hurt") + usr.visible_message("\red [user] draws the [holstered], ready to shoot!
    ", \ + "You draw the [holstered], ready to shoot!") + else + user.visible_message("[user] draws the [holstered], pointing it at the ground.", \ + "You draw the [holstered], pointing it at the ground.") + user.put_in_hands(holstered) + holstered.add_fingerprint(user) + holstered = null + +/obj/item/clothing/accessory/holster/attack_hand(mob/user as mob) + if (has_suit) //if we are part of a suit + if (holstered) + unholster(user) + return + + ..(user) + +/obj/item/clothing/accessory/holster/attackby(obj/item/W as obj, mob/user as mob, params) + holster(W, user) + +/obj/item/clothing/accessory/holster/emp_act(severity) + if (holstered) + holstered.emp_act(severity) + ..() + +/obj/item/clothing/accessory/holster/examine(mob/user) + ..(user) + if (holstered) + user << "A [holstered] is holstered here." + else + user << "It is empty." + +/obj/item/clothing/accessory/holster/on_attached(obj/item/clothing/under/S, mob/user as mob) + ..() + has_suit.verbs += /obj/item/clothing/accessory/holster/verb/holster_verb + +/obj/item/clothing/accessory/holster/on_removed(mob/user as mob) + has_suit.verbs -= /obj/item/clothing/accessory/holster/verb/holster_verb + ..() + +//For the holster hotkey +/obj/item/clothing/accessory/holster/verb/holster_verb() + set name = "Holster" + set category = "Object" + set src in usr + if(!istype(usr, /mob/living)) return + if(usr.stat) return + + var/obj/item/clothing/accessory/holster/H = null + if (istype(src, /obj/item/clothing/accessory/holster)) + H = src + else if (istype(src, /obj/item/clothing/under)) + var/obj/item/clothing/under/S = src + if (S.accessories.len) + H = locate() in S.accessories + + if (!H) + usr << "Something is very wrong." + + if(!H.holstered) + if(!istype(usr.get_active_hand(), /obj/item/weapon/gun)) + usr << "You need your gun equiped to holster it." + return + var/obj/item/weapon/gun/W = usr.get_active_hand() + H.holster(W, usr) + else + H.unholster(usr) + +/obj/item/clothing/accessory/holster/armpit + name = "shoulder holster" + desc = "A worn-out handgun holster. Perfect for concealed carry" + icon_state = "holster" + _color = "holster" + holster_allow = /obj/item/weapon/gun/projectile + +/obj/item/clothing/accessory/holster/waist + name = "shoulder holster" + desc = "A handgun holster. Made of expensive leather." + icon_state = "holster" + _color = "holster_low" \ No newline at end of file diff --git a/code/modules/clothing/under/accessories/storage.dm b/code/modules/clothing/under/accessories/storage.dm new file mode 100644 index 00000000000..d33d5e9a263 --- /dev/null +++ b/code/modules/clothing/under/accessories/storage.dm @@ -0,0 +1,105 @@ +/obj/item/clothing/accessory/storage + name = "load bearing equipment" + desc = "Used to hold things when you don't have enough hands." + icon_state = "webbing" + _color = "webbing" + slot = "utility" + var/slots = 3 + var/obj/item/weapon/storage/internal/hold + icon_action_button = "action_storage" + w_class = 3.0 // so it doesn't fit in pockets + +/obj/item/clothing/accessory/storage/New() + ..() + hold = new/obj/item/weapon/storage/internal(src) + hold.storage_slots = slots + +/obj/item/clothing/accessory/storage/attack_hand(mob/user as mob) + if (has_suit) //if we are part of a suit + hold.open(user) + return + + if (hold.handle_attack_hand(user)) //otherwise interact as a regular storage item + ..(user) + +/obj/item/clothing/accessory/storage/MouseDrop(obj/over_object as obj) + if (has_suit) + return + + if (hold.handle_mousedrop(usr, over_object)) + ..(over_object) + +/obj/item/clothing/accessory/storage/attackby(obj/item/W as obj, mob/user as mob, params) + return hold.attackby(W, user, params) + +/obj/item/clothing/accessory/storage/emp_act(severity) + hold.emp_act(severity) + ..() + +/obj/item/clothing/accessory/storage/hear_talk(mob/M, var/msg, verb, datum/language/speaking) + hold.hear_talk(M, msg, verb, speaking) + ..() + +/obj/item/clothing/accessory/storage/proc/return_inv() + + var/list/L = list( ) + + L += src.contents + + for(var/obj/item/weapon/storage/S in src) + L += S.return_inv() + for(var/obj/item/weapon/gift/G in src) + L += G.gift + if (istype(G.gift, /obj/item/weapon/storage)) + L += G.gift:return_inv() + return L + +/obj/item/clothing/accessory/storage/attack_self(mob/user as mob) + if (has_suit) //if we are part of a suit + hold.open(user) + else + user << "You empty [src]." + var/turf/T = get_turf(src) + hold.hide_from(usr) + for(var/obj/item/I in hold.contents) + hold.remove_from_storage(I, T) + src.add_fingerprint(user) + +/obj/item/clothing/accessory/storage/webbing + name = "webbing" + desc = "Sturdy mess of synthcotton belts and buckles, ready to share your burden." + icon_state = "webbing" + _color = "webbing" + +/obj/item/clothing/accessory/storage/black_vest + name = "black webbing vest" + desc = "Robust black synthcotton vest with lots of pockets to hold whatever you need, but cannot hold in hands." + icon_state = "vest_black" + _color = "vest_black" + slots = 5 + +/obj/item/clothing/accessory/storage/brown_vest + name = "brown webbing vest" + desc = "Worn brownish synthcotton vest with lots of pockets to unload your hands." + icon_state = "vest_brown" + _color = "vest_brown" + slots = 5 + +/obj/item/clothing/accessory/storage/knifeharness + name = "decorated harness" + desc = "A heavily decorated harness of sinew and leather with two knife-loops." + icon_state = "unathiharness2" + _color = "unathiharness2" + slots = 2 + +/obj/item/clothing/accessory/storage/knifeharness/New() + ..() + hold.max_combined_w_class = 4 + hold.can_hold = list("/obj/item/weapon/hatchet/unathiknife",\ + "/obj/item/weapon/kitchen/utensil/knife",\ + "/obj/item/weapon/kitchen/utensil/pknife",\ + "/obj/item/weapon/kitchenknife",\ + "/obj/item/weapon/kitchenknife/ritual") + + new /obj/item/weapon/hatchet/unathiknife(hold) + new /obj/item/weapon/hatchet/unathiknife(hold) \ No newline at end of file diff --git a/code/modules/clothing/under/chameleon.dm b/code/modules/clothing/under/chameleon.dm index 21147299397..3e51b7b267e 100644 --- a/code/modules/clothing/under/chameleon.dm +++ b/code/modules/clothing/under/chameleon.dm @@ -21,7 +21,7 @@ return - attackby(obj/item/clothing/under/U as obj, mob/user as mob) + attackby(obj/item/clothing/under/U as obj, mob/user as mob, params) ..() if(istype(U, /obj/item/clothing/under/chameleon)) user << "\red Nothing happens." diff --git a/code/modules/clothing/under/color.dm b/code/modules/clothing/under/color.dm index dc292acf7e3..b5f276c2539 100644 --- a/code/modules/clothing/under/color.dm +++ b/code/modules/clothing/under/color.dm @@ -15,7 +15,7 @@ icon_state = "black" item_state = "bl_suit" _color = "black" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/under/color/blackf name = "feminine black jumpsuit" @@ -29,17 +29,17 @@ icon_state = "blue" item_state = "b_suit" _color = "blue" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/under/color/blue/dodgeball - canremove = 0 + flags = ONESIZEFITSALL | NODROP /obj/item/clothing/under/color/green name = "green jumpsuit" icon_state = "green" item_state = "g_suit" _color = "green" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/under/color/grey name = "grey jumpsuit" @@ -47,7 +47,7 @@ icon_state = "grey" item_state = "gy_suit" _color = "grey" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") /obj/item/clothing/under/color/orange @@ -56,7 +56,7 @@ icon_state = "orange" item_state = "o_suit" _color = "orange" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/under/color/orange/prison name = "orange jumpsuit" @@ -66,7 +66,7 @@ _color = "orange" has_sensor = 2 sensor_mode = 3 - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/under/color/pink name = "pink jumpsuit" @@ -74,31 +74,31 @@ icon_state = "pink" item_state = "p_suit" _color = "pink" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/under/color/red name = "red jumpsuit" icon_state = "red" item_state = "r_suit" _color = "red" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/under/color/red/dodgeball - canremove = 0 + flags = ONESIZEFITSALL | NODROP /obj/item/clothing/under/color/white name = "white jumpsuit" icon_state = "white" item_state = "w_suit" _color = "white" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/under/color/yellow name = "yellow jumpsuit" icon_state = "yellow" item_state = "y_suit" _color = "yellow" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/under/psyche name = "psychedelic jumpsuit" @@ -115,7 +115,7 @@ name = "aqua jumpsuit" icon_state = "aqua" _color = "aqua" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/under/color/purple name = "purple jumpsuit" @@ -142,13 +142,12 @@ name = "light brown jumpsuit" icon_state = "lightbrown" _color = "lightbrown" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/under/color/brown name = "brown jumpsuit" icon_state = "brown" _color = "brown" - flags = FPRINT | TABLEPASS /obj/item/clothing/under/color/yellowgreen name = "yellow green jumpsuit" @@ -159,7 +158,7 @@ name = "dark blue jumpsuit" icon_state = "darkblue" _color = "darkblue" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/under/color/lightred name = "light red jumpsuit" @@ -170,4 +169,4 @@ name = "dark red jumpsuit" icon_state = "darkred" _color = "darkred" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL diff --git a/code/modules/clothing/under/jobs/civilian.dm b/code/modules/clothing/under/jobs/civilian.dm index 48085322d6f..6510fff5094 100644 --- a/code/modules/clothing/under/jobs/civilian.dm +++ b/code/modules/clothing/under/jobs/civilian.dm @@ -6,7 +6,7 @@ icon_state = "ba_suit" item_state = "ba_suit" _color = "ba_suit" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -18,7 +18,7 @@ icon_state = "captain" item_state = "caparmor" _color = "captain" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -31,7 +31,7 @@ icon_state = "qm" item_state = "lb_suit" _color = "qm" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -44,7 +44,7 @@ icon_state = "cargotech" item_state = "lb_suit" _color = "cargo" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -57,7 +57,7 @@ icon_state = "chaplain" item_state = "bl_suit" _color = "chapblack" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -69,7 +69,7 @@ name = "chef's uniform" icon_state = "chef" _color = "chef" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -82,7 +82,7 @@ icon_state = "clown" item_state = "clown" _color = "clown" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/under/rank/head_of_personnel @@ -91,7 +91,7 @@ icon_state = "hop" item_state = "b_suit" _color = "hop" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -103,7 +103,6 @@ icon_state = "hopwhimsy" item_state = "hopwhimsy" _color = "hopwhimsy" - flags = FPRINT | TABLEPASS /obj/item/clothing/under/rank/hydroponics @@ -113,7 +112,7 @@ item_state = "g_suit" _color = "hydroponics" permeability_coefficient = 0.50 - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -126,7 +125,7 @@ icon_state = "internalaffairs" item_state = "internalaffairs" _color = "internalaffairs" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -139,7 +138,7 @@ icon_state = "janitor" _color = "janitor" armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -149,7 +148,7 @@ /obj/item/clothing/under/lawyer desc = "Slick threads." name = "Lawyer suit" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/under/lawyer/black icon_state = "lawyer_black" @@ -226,7 +225,7 @@ icon_state = "red_suit" item_state = "red_suit" _color = "red_suit" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -239,7 +238,7 @@ icon_state = "mime" item_state = "mime" _color = "mime" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/under/rank/miner @@ -248,7 +247,7 @@ icon_state = "miner" item_state = "miner" _color = "miner" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' diff --git a/code/modules/clothing/under/jobs/engineering.dm b/code/modules/clothing/under/jobs/engineering.dm index a0539901c5d..75e8f01d7e9 100644 --- a/code/modules/clothing/under/jobs/engineering.dm +++ b/code/modules/clothing/under/jobs/engineering.dm @@ -6,7 +6,7 @@ item_state = "g_suit" _color = "chief" armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 10) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -18,7 +18,7 @@ icon_state = "atmos" item_state = "atmos_suit" _color = "atmos" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -31,7 +31,7 @@ item_state = "engi_suit" _color = "engine" armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 10) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -43,7 +43,7 @@ icon_state = "robotics" item_state = "robotics" _color = "robotics" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' diff --git a/code/modules/clothing/under/jobs/medsci.dm b/code/modules/clothing/under/jobs/medsci.dm index 1332f80c6eb..93baad2f1a4 100644 --- a/code/modules/clothing/under/jobs/medsci.dm +++ b/code/modules/clothing/under/jobs/medsci.dm @@ -8,7 +8,7 @@ item_state = "g_suit" _color = "director" armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 10, bio = 10, rad = 0) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -22,7 +22,7 @@ _color = "toxinswhite" permeability_coefficient = 0.50 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 10, bio = 0, rad = 0) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -36,7 +36,7 @@ _color = "chemistrywhite" permeability_coefficient = 0.50 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -53,7 +53,7 @@ _color = "cmo" permeability_coefficient = 0.50 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -67,7 +67,7 @@ _color = "geneticswhite" permeability_coefficient = 0.50 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -81,7 +81,7 @@ _color = "virologywhite" permeability_coefficient = 0.50 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -95,7 +95,7 @@ _color = "nursesuit" permeability_coefficient = 0.50 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -109,7 +109,7 @@ _color = "nurse" permeability_coefficient = 0.50 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -123,7 +123,7 @@ _color = "orderly" permeability_coefficient = 0.50 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -137,7 +137,7 @@ _color = "medical" permeability_coefficient = 0.50 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -148,7 +148,7 @@ desc = "It's made of a special fiber that provides minor protection against biohazards. This one is in baby blue." icon_state = "scrubsblue" _color = "scrubsblue" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -159,7 +159,7 @@ desc = "It's made of a special fiber that provides minor protection against biohazards. This one is in dark green." icon_state = "scrubsgreen" _color = "scrubsgreen" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -170,7 +170,7 @@ desc = "It's made of a special fiber that provides minor protection against biohazards. This one is in deep purple." icon_state = "scrubspurple" _color = "scrubspurple" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -181,7 +181,7 @@ desc = "It's made of a special fiber that provides minor protection against biohazards. This one is as dark as an emo's poetry." icon_state = "scrubsblack" _color = "scrubsblack" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -196,7 +196,7 @@ _color = "paramedic" permeability_coefficient = 0.50 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 10) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/uniform.dmi' @@ -208,7 +208,7 @@ icon_state = "psych" item_state = "w_suit" _color = "psych" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/under/rank/psych/turtleneck desc = "A turqouise turtleneck and a pair of dark blue slacks, belonging to a psychologist." @@ -216,7 +216,7 @@ icon_state = "psychturtle" item_state = "b_suit" _color = "psychturtle" - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /* @@ -230,7 +230,7 @@ _color = "genetics_new" permeability_coefficient = 0.50 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/under/rank/chemist_new desc = "It's made of a special fiber which provides minor protection against biohazards." @@ -240,7 +240,7 @@ _color = "chemist_new" permeability_coefficient = 0.50 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/under/rank/scientist_new desc = "Made of a special fiber that gives special protection against biohazards and small explosions." @@ -250,7 +250,7 @@ _color = "scientist_new" permeability_coefficient = 0.50 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 10, bio = 0, rad = 0) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/under/rank/virologist_new desc = "Made of a special fiber that gives increased protection against biohazards." @@ -260,4 +260,4 @@ _color = "virologist_new" permeability_coefficient = 0.50 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL diff --git a/code/modules/clothing/under/jobs/security.dm b/code/modules/clothing/under/jobs/security.dm index 807f5322056..a0f6d97ad14 100644 --- a/code/modules/clothing/under/jobs/security.dm +++ b/code/modules/clothing/under/jobs/security.dm @@ -15,7 +15,7 @@ item_state = "r_suit" _color = "warden" armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL siemens_coefficient = 0.9 /obj/item/clothing/under/rank/security @@ -25,7 +25,7 @@ item_state = "r_suit" _color = "secred" armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL siemens_coefficient = 0.9 /obj/item/clothing/under/rank/dispatch @@ -35,7 +35,7 @@ item_state = "dispatch" _color = "dispatch" armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL siemens_coefficient = 0.9 /obj/item/clothing/under/rank/security2 @@ -45,7 +45,7 @@ item_state = "r_suit" _color = "redshirt2" armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL siemens_coefficient = 0.9 /obj/item/clothing/under/rank/security/corp @@ -68,7 +68,7 @@ item_state = "det" _color = "detective" armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL siemens_coefficient = 0.9 /* @@ -81,7 +81,7 @@ item_state = "r_suit" _color = "hosred" armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL siemens_coefficient = 0.8 /obj/item/clothing/under/rank/head_of_security/corp @@ -97,7 +97,7 @@ item_state = "jensen" _color = "jensen" siemens_coefficient = 0.6 - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL //Paradise Station diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 84ac2feac52..114b0c16db3 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -31,7 +31,6 @@ name = "amish suit" icon_state = "sl_suit" _color = "sl_suit" - flags = FPRINT | TABLEPASS /obj/item/clothing/under/waiter name = "waiter's outfit" @@ -39,7 +38,6 @@ icon_state = "waiter" item_state = "waiter" _color = "waiter" - flags = FPRINT | TABLEPASS /obj/item/clothing/under/rank/mailman name = "mailman's jumpsuit" @@ -83,7 +81,7 @@ item_state = "g_suit" _color = "officer" displays_id = 0 - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/under/rank/centcom/captain desc = "Gold trim on space-black cloth, this uniform displays the rank of \"Captain\" and bears \"N.C.V. Fearless CV-286\" on the left shounder." @@ -100,7 +98,7 @@ item_state = "g_suit" _color = "officer" displays_id = 0 - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/under/rank/centcom/representative desc = "Gold trim on space-black cloth, this uniform displays the rank of \"Ensign\" and bears \"N.S.S. Cyberiad\" on the left shounder." @@ -109,7 +107,7 @@ item_state = "g_suit" _color = "officer" displays_id = 0 - flags = FPRINT | TABLEPASS | ONESIZEFITSALL + flags = ONESIZEFITSALL /obj/item/clothing/under/space name = "\improper NASA jumpsuit" @@ -120,7 +118,6 @@ w_class = 4//bulky item gas_transfer_coefficient = 0.01 permeability_coefficient = 0.02 - flags = FPRINT | TABLEPASS body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | ARMS //Needs gloves and shoes with cold protection to be fully protected. min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE @@ -135,7 +132,6 @@ desc = "it's a cybernetically enhanced jumpsuit used for administrative duties." gas_transfer_coefficient = 0.01 permeability_coefficient = 0.01 - flags = FPRINT | TABLEPASS body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS armor = list(melee = 100, bullet = 100, laser = 100,energy = 100, bomb = 100, bio = 100, rad = 100) cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS @@ -144,13 +140,6 @@ max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE siemens_coefficient = 0 -/obj/item/clothing/under/owl - name = "owl uniform" - desc = "A jumpsuit with owl wings. Photorealistic owl feathers! Twooooo!" - icon_state = "owl" - _color = "owl" - flags = FPRINT | TABLEPASS - /obj/item/clothing/under/johnny name = "johnny~~ jumpsuit" desc = "Johnny~~" @@ -228,6 +217,27 @@ item_state = "navy_suit" _color = "navy_suit" +/obj/item/clothing/under/suit_jacket/tan + name = "tan suit" + desc = "A tan suit with a yellow tie. Smart, but casual." + icon_state = "tan_suit" + item_state = "tan_suit" + _color = "tan_suit" + +/obj/item/clothing/under/suit_jacket/burgundy + name = "burgundy suit" + desc = "A burgundy suit and black tie. Somewhat formal." + icon_state = "burgundy_suit" + item_state = "burgundy_suit" + _color = "burgundy_suit" + +/obj/item/clothing/under/suit_jacket/charcoal + name = "charcoal suit" + desc = "A charcoal suit and red tie. Very professional." + icon_state = "charcoal_suit" + item_state = "charcoal_suit" + _color = "charcoal_suit" + /obj/item/clothing/under/blackskirt name = "black skirt" desc = "A black skirt, very fancy!" @@ -587,6 +597,13 @@ _color = "pennywise" body_parts_covered = UPPER_TORSO|LOWER_TORSO +/obj/item/clothing/under/assistantformal + name = "assistant's formal uniform" + desc = "An assistant's formal-wear. Why an assistant needs formal-wear is still unknown." + icon_state = "assistant_formal" + item_state = "gy_suit" + _color = "assistant_formal" + /obj/item/clothing/under/blacktango name = "black tango dress" desc = "Filled with Latin fire." @@ -620,4 +637,19 @@ desc = "That's a very nice suit you have there. Shame if something were to happen to it, eh?" icon_state = "checkered_suit" item_state = "checkered_suit" - _color = "checkered_suit" \ No newline at end of file + _color = "checkered_suit" + +/obj/item/clothing/under/owl + name = "owl uniform" + desc = "A soft brown jumpsuit made of synthetic feathers and strong conviction." + icon_state = "owl" + _color = "owl" + flags = NODROP + +/obj/item/clothing/under/griffin + name = "griffon uniform" + desc = "A soft brown jumpsuit with a white feather collar made of synthetic feathers and a lust for mayhem." + icon_state = "griffin" + _color = "griffin" + flags = NODROP + \ No newline at end of file diff --git a/code/modules/clothing/under/pants.dm b/code/modules/clothing/under/pants.dm index 052eb50dd6f..0a1d3c49aba 100644 --- a/code/modules/clothing/under/pants.dm +++ b/code/modules/clothing/under/pants.dm @@ -78,4 +78,11 @@ name = "camo pants" desc = "A pair of woodland camouflage pants. Probably not the best choice for a space station." icon_state = "camopants" - _color = "camopants" \ No newline at end of file + _color = "camopants" + +/obj/item/clothing/under/pants/chaps + name = "black leather assless chaps" + desc = "For those brave enough to weather the breeze." + icon_state = "chaps" + _color = "chaps" + flags = ONESIZEFITSALL \ No newline at end of file diff --git a/code/modules/clothing/under/shorts.dm b/code/modules/clothing/under/shorts.dm index 92fc9f3f131..f5280399838 100644 --- a/code/modules/clothing/under/shorts.dm +++ b/code/modules/clothing/under/shorts.dm @@ -2,7 +2,6 @@ name = "athletic shorts" desc = "95% Polyester, 5% Spandex!" gender = PLURAL - flags = FPRINT | TABLEPASS body_parts_covered = LOWER_TORSO /obj/item/clothing/under/shorts/red diff --git a/code/modules/clothing/under/ties.dm b/code/modules/clothing/under/ties.dm deleted file mode 100644 index 5bf9e1cb75f..00000000000 --- a/code/modules/clothing/under/ties.dm +++ /dev/null @@ -1,467 +0,0 @@ -/obj/item/clothing/tie - name = "tie" - desc = "A neosilk clip-on tie." - icon = 'icons/obj/clothing/ties.dmi' - icon_state = "bluetie" - item_state = "" //no inhands - _color = "bluetie" - flags = FPRINT | TABLEPASS - slot_flags = 0 - w_class = 2.0 - -/obj/item/clothing/tie/blue - name = "blue tie" - icon_state = "bluetie" - _color = "bluetie" - -/obj/item/clothing/tie/red - name = "red tie" - icon_state = "redtie" - _color = "redtie" - -/obj/item/clothing/tie/black - name = "black tie" - icon_state = "blacktie" - _color = "blacktie" - -/obj/item/clothing/tie/horrible - name = "horrible tie" - desc = "A neosilk clip-on tie. This one is disgusting." - icon_state = "horribletie" - _color = "horribletie" - -/obj/item/clothing/tie/waistcoat - name = "waistcoat" - desc = "For some classy, murderous fun." - icon_state = "waistcoat" - item_state = "waistcoat" - _color = "waistcoat" - -/obj/item/clothing/tie/stethoscope - name = "stethoscope" - desc = "An outdated medical apparatus for listening to the sounds of the human body. It also makes you look like you know what you're doing." - icon_state = "stethoscope" - _color = "stethoscope" - -/obj/item/clothing/tie/stethoscope/attack(mob/living/carbon/human/M, mob/living/user) - if(ishuman(M) && isliving(user)) - if(user.a_intent == "help") - var/body_part = parse_zone(user.zone_sel.selecting) - if(body_part) - var/their = "their" - switch(M.gender) - if(MALE) their = "his" - if(FEMALE) their = "her" - - var/sound = "pulse" - var/sound_strength - - if(M.stat == DEAD || (M.status_flags&FAKEDEATH)) - sound_strength = "cannot hear" - sound = "anything" - else - sound_strength = "hear a weak" - switch(body_part) - if("chest") - if(M.oxyloss < 50) - sound_strength = "hear a healthy" - sound = "pulse and respiration" - if("eyes","mouth") - sound_strength = "cannot hear" - sound = "anything" - else - sound_strength = "hear a weak" - - user.visible_message("[user] places [src] against [M]'s [body_part] and listens attentively.", "You place [src] against [their] [body_part]. You [sound_strength] [sound].") - return - return ..(M,user) - - -//Medals -/obj/item/clothing/tie/medal - name = "bronze medal" - desc = "A bronze medal." - icon_state = "bronze" - _color = "bronze" - -/obj/item/clothing/tie/medal/conduct - name = "distinguished conduct medal" - desc = "A bronze medal awarded for distinguished conduct. Whilst a great honor, this is most basic award given by Nanotrasen. It is often awarded by a captain to a member of his crew." - -/obj/item/clothing/tie/medal/bronze_heart - name = "bronze heart medal" - desc = "A bronze heart-shaped medal awarded for sacrifice. It is often awarded posthumously or for severe injury in the line of duty." - icon_state = "bronze_heart" - -/obj/item/clothing/tie/medal/nobel_science - name = "nobel sciences award" - desc = "A bronze medal which represents significant contributions to the field of science or engineering." - -/obj/item/clothing/tie/medal/silver - name = "silver medal" - desc = "A silver medal." - icon_state = "silver" - _color = "silver" - -/obj/item/clothing/tie/medal/silver/valor - name = "medal of valor" - desc = "A silver medal awarded for acts of exceptional valor." - -/obj/item/clothing/tie/medal/silver/security - name = "robust security award" - desc = "An award for distinguished combat and sacrifice in defence of Nanotrasen's commercial interests. Often awarded to security staff." - -/obj/item/clothing/tie/medal/gold - name = "gold medal" - desc = "A prestigious golden medal." - icon_state = "gold" - _color = "gold" - -/obj/item/clothing/tie/medal/gold/captain - name = "medal of captaincy" - desc = "A golden medal awarded exclusively to those promoted to the rank of captain. It signifies the codified responsibilities of a captain to Nanotrasen, and their undisputable authority over their crew." - -/obj/item/clothing/tie/medal/gold/heroism - name = "medal of exceptional heroism" - desc = "An extremely rare golden medal awarded only by CentComm. To recieve such a medal is the highest honor and as such, very few exist. This medal is almost never awarded to anybody but commanders." - -/obj/item/clothing/tie/medal/gold/ion - name = "Ion Chef Medal" - desc = "A medal awarded to the winner of the Ion Chef contest" - icon_state = "ion" - _color = "ion" - - -//Armbands -/obj/item/clothing/tie/armband - name = "red armband" - desc = "An fancy red armband!" - icon_state = "red" - _color = "red" - -/obj/item/clothing/tie/armband/cargo - name = "cargo bay guard armband" - desc = "An armband, worn by the station's security forces to display which department they're assigned to. This one is brown." - icon_state = "cargo" - _color = "cargo" - -/obj/item/clothing/tie/armband/engine - name = "engineering guard armband" - desc = "An armband, worn by the station's security forces to display which department they're assigned to. This one is orange with a reflective strip!" - icon_state = "engie" - _color = "engie" - -/obj/item/clothing/tie/armband/science - name = "science guard armband" - desc = "An armband, worn by the station's security forces to display which department they're assigned to. This one is purple." - icon_state = "rnd" - _color = "rnd" - -/obj/item/clothing/tie/armband/hydro - name = "hydroponics guard armband" - desc = "An armband, worn by the station's security forces to display which department they're assigned to. This one is green and blue." - icon_state = "hydro" - _color = "hydro" - -/obj/item/clothing/tie/armband/med - name = "medical guard armband" - desc = "An armband, worn by the station's security forces to display which department they're assigned to. This one is white." - icon_state = "med" - _color = "med" - -/obj/item/clothing/tie/armband/medgreen - name = "medical guard armband" - desc = "An armband, worn by the station's security forces to display which department they're assigned to. This one is white and green." - icon_state = "medgreen" - _color = "medgreen" - -/obj/item/clothing/tie/holster - name = "large shoulder holster" - desc = "A handgun holster." - icon_state = "holster" - _color = "holster" - var/obj/item/weapon/gun/holstered = null - var/holster_allow = /obj/item/weapon/gun - icon_action_button = "action_holster" - -/obj/item/clothing/tie/holster/attack_self() - holster() - -/obj/item/clothing/tie/holster/proc/holster() - if(!istype(usr, /mob/living)) return - if(usr.stat) return - - if(!holstered) - if(!istype(usr.get_active_hand(), holster_allow)) - usr << "You can't fit that in the holster." - return - var/obj/item/weapon/gun/W = usr.get_active_hand() - if (!W.isHandgun()) - usr << "This gun won't fit in \the [src]!" - return - holstered = usr.get_active_hand() - usr.drop_item() - holstered.loc = src - usr.visible_message("\The [usr] holsters \the [holstered].", "You holster \the [holstered].") - else - if(istype(usr.get_active_hand(),/obj) && istype(usr.get_inactive_hand(),/obj)) - usr << "You need an empty hand to draw the gun!" - else - if(usr.a_intent == "harm") - usr.visible_message("\The [usr] draws \the [holstered], ready to shoot!", \ - "You draw \the [holstered], ready to shoot!") - else - usr.visible_message("\The [usr] draws \the [holstered], pointing it at the ground.", \ - "You draw \the [holstered], pointing it at the ground.") - usr.put_in_hands(holstered) - holstered = null - -/obj/item/clothing/tie/holster/armpit - name = "shoulder holster" - desc = "A worn-out handgun holster. Perfect for concealed carry" - icon_state = "holster" - _color = "holster" - holster_allow = /obj/item/weapon/gun/projectile - -/obj/item/clothing/tie/storage - name = "load bearing equipment" - desc = "Used to hold things when you don't have enough hands for that." - icon_state = "webbing" - _color = "webbing" - var/slots = 3 - var/obj/item/weapon/storage/pockets/hold - icon_action_button = "action_storage" - -/obj/item/clothing/tie/storage/New() - hold = new /obj/item/weapon/storage/pockets(src) - hold.master_item = src - hold.storage_slots = slots - - -/obj/item/clothing/tie/storage/attack_self(mob/user as mob) - if (!istype(hold)) - return - - hold.loc = user - hold.attack_hand(user) - -/obj/item/clothing/tie/storage/attackby(obj/item/weapon/W as obj, mob/user as mob) - hold.attackby(W,user) - src.add_fingerprint(user) - -/obj/item/weapon/storage/pockets - name = "storage" - var/master_item //item it belongs to - -/obj/item/weapon/storage/pockets/close(mob/user as mob) - ..() - loc = master_item - -/obj/item/clothing/tie/storage/webbing - name = "webbing" - desc = "Strudy mess of synthcotton belts and buckles, ready to share your burden." - icon_state = "webbing" - _color = "webbing" - -/obj/item/clothing/tie/storage/black_vest - name = "black webbing vest" - desc = "Robust black synthcotton vest with lots of pockets to hold whatever you need, but cannot hold in hands." - icon_state = "vest_black" - _color = "vest_black" - slots = 5 - -/obj/item/clothing/tie/storage/brown_vest - name = "brown webbing vest" - desc = "Worn brownish synthcotton vest with lots of pockets to unload your hands." - icon_state = "vest_brown" - _color = "vest_brown" - slots = 5 -/* - Holobadges are worn on the belt or neck, and can be used to show that the holder is an authorized - Security agent - the user details can be imprinted on the badge with a Security-access ID card, - or they can be emagged to accept any ID for use in disguises. -*/ - -/obj/item/clothing/tie/holobadge - - name = "holobadge" - desc = "This glowing blue badge marks the holder as THE LAW." - icon_state = "holobadge" - _color = "holobadge" - slot_flags = SLOT_BELT - - var/emagged = 0 //Emagging removes Sec check. - var/stored_name = null - -/obj/item/clothing/tie/holobadge/cord - icon_state = "holobadge-cord" - _color = "holobadge-cord" - slot_flags = SLOT_MASK - -/obj/item/clothing/tie/holobadge/attack_self(mob/user as mob) - if(!stored_name) - user << "Waving around a badge before swiping an ID would be pretty pointless." - return - if(isliving(user)) - user.visible_message("\red [user] displays their Nanotrasen Internal Security Legal Authorization Badge.\nIt reads: [stored_name], NT Security.","\red You display your Nanotrasen Internal Security Legal Authorization Badge.\nIt reads: [stored_name], NT Security.") - -/obj/item/clothing/tie/holobadge/attackby(var/obj/item/O as obj, var/mob/user as mob) - - if (istype(O, /obj/item/weapon/card/emag)) - if (emagged) - user << "\red [src] is already cracked." - return - else - emagged = 1 - user << "\red You swipe [O] and crack the holobadge security checks." - return - - else if(istype(O, /obj/item/weapon/card/id) || istype(O, /obj/item/device/pda)) - - var/obj/item/weapon/card/id/id_card = null - - if(istype(O, /obj/item/weapon/card/id)) - id_card = O - else - var/obj/item/device/pda/pda = O - id_card = pda.id - - if(access_security in id_card.access || emagged) - user << "You imprint your ID details onto the badge." - stored_name = id_card.registered_name - name = "holobadge ([stored_name])" - desc = "This glowing blue badge marks [stored_name] as THE LAW." - else - user << "[src] rejects your insufficient access rights." - return - ..() - -/obj/item/clothing/tie/holobadge/attack(mob/living/carbon/human/M, mob/living/user) - if(isliving(user)) - user.visible_message("\red [user] invades [M]'s personal space, thrusting [src] into their face insistently.","\red You invade [M]'s personal space, thrusting [src] into their face insistently. You are the law.") - -/obj/item/weapon/storage/box/holobadge - name = "holobadge box" - desc = "A box claiming to contain holobadges." - New() - new /obj/item/clothing/tie/holobadge(src) - new /obj/item/clothing/tie/holobadge(src) - new /obj/item/clothing/tie/holobadge(src) - new /obj/item/clothing/tie/holobadge(src) - new /obj/item/clothing/tie/holobadge/cord(src) - new /obj/item/clothing/tie/holobadge/cord(src) - ..() - return - -/obj/item/clothing/tie/storage/knifeharness - name = "decorated harness" - desc = "A heavily decorated harness of sinew and leather with two knife-loops." - icon_state = "unathiharness2" - _color = "unathiharness2" - slots = 2 - -/obj/item/clothing/tie/storage/knifeharness/attackby(var/obj/item/O as obj, mob/user as mob) - ..() - update() - -/obj/item/clothing/tie/storage/knifeharness/proc/update() - var/count = 0 - for(var/obj/item/I in hold) - if(istype(I,/obj/item/weapon/hatchet/unathiknife)) - count++ - if(count>2) count = 2 - item_state = "unathiharness[count]" - icon_state = item_state - _color = item_state - - if(istype(loc, /obj/item/clothing)) - var/obj/item/clothing/U = loc - if(istype(U.loc, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = U.loc - H.update_inv_w_uniform() - -/obj/item/clothing/tie/storage/knifeharness/New() - ..() - new /obj/item/weapon/hatchet/unathiknife(hold) - new /obj/item/weapon/hatchet/unathiknife(hold) - -/////////// -//SCARVES// -/////////// - -/obj/item/clothing/tie/scarf - name = "scarf" - desc = "A stylish scarf. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their necks." - -/obj/item/clothing/tie/scarf/red - name = "red scarf" - icon_state = "redscarf" - _color = "redscarf" - -/obj/item/clothing/tie/scarf/green - name = "green scarf" - icon_state = "greenscarf" - _color = "greenscarf" - -/obj/item/clothing/tie/scarf/darkblue - name = "dark blue scarf" - icon_state = "darkbluescarf" - _color = "darkbluescarf" - -/obj/item/clothing/tie/scarf/purple - name = "purple scarf" - icon_state = "purplescarf" - _color = "purplescarf" - -/obj/item/clothing/tie/scarf/yellow - name = "yellow scarf" - icon_state = "yellowscarf" - _color = "yellowscarf" - -/obj/item/clothing/tie/scarf/orange - name = "orange scarf" - icon_state = "orangescarf" - _color = "orangescarf" - -/obj/item/clothing/tie/scarf/lightblue - name = "light blue scarf" - icon_state = "lightbluescarf" - _color = "lightbluescarf" - -/obj/item/clothing/tie/scarf/white - name = "white scarf" - icon_state = "whitescarf" - _color = "whitescarf" - -/obj/item/clothing/tie/scarf/black - name = "black scarf" - icon_state = "blackscarf" - _color = "blackscarf" - -/obj/item/clothing/tie/scarf/zebra - name = "zebra scarf" - icon_state = "zebrascarf" - _color = "zebrascarf" - -/obj/item/clothing/tie/scarf/christmas - name = "christmas scarf" - icon_state = "christmasscarf" - _color = "christmasscarf" - -//The three following scarves don't have the scarf subtype -//This is because Ian can equip anything from that subtype -//However, these 3 don't have corgi versions of their sprites -/obj/item/clothing/tie/stripedredscarf - name = "striped red scarf" - icon_state = "stripedredscarf" - _color = "stripedredscarf" - -/obj/item/clothing/tie/stripedgreenscarf - name = "striped green scarf" - icon_state = "stripedgreenscarf" - _color = "stripedgreenscarf" - -/obj/item/clothing/tie/stripedbluescarf - name = "striped blue scarf" - icon_state = "stripedbluescarf" - _color = "stripedbluescarf" \ No newline at end of file diff --git a/code/modules/computer3/buildandrepair.dm b/code/modules/computer3/buildandrepair.dm index 38db742ee67..277d0f538c8 100644 --- a/code/modules/computer3/buildandrepair.dm +++ b/code/modules/computer3/buildandrepair.dm @@ -61,7 +61,7 @@ // Battery must be installed BEFORE wiring the computer. // if installing it in an existing computer, you will have to // get back to this state first. - var/obj/item/weapon/cell/battery = null + var/obj/item/weapon/stock_parts/cell/battery = null /obj/structure/computer3frame/server name = "server frame" @@ -76,7 +76,7 @@ completed = /obj/machinery/computer3/laptop max_components = 3 -/obj/structure/computer3frame/attackby(obj/item/P as obj, mob/user as mob) +/obj/structure/computer3frame/attackby(obj/item/P as obj, mob/user as mob, params) switch(state) if(0) if(istype(P, /obj/item/weapon/wrench)) @@ -143,7 +143,7 @@ else user << "\red There's no battery to remove!" - if(istype(P, /obj/item/weapon/cell)) + if(istype(P, /obj/item/weapon/stock_parts/cell)) if(!battery) playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) if(do_after(5)) diff --git a/code/modules/computer3/component.dm b/code/modules/computer3/component.dm index 501bbc973eb..739c2472e4c 100644 --- a/code/modules/computer3/component.dm +++ b/code/modules/computer3/component.dm @@ -24,7 +24,7 @@ // If the computer is attacked by an item it will reference this to decide which peripheral(s) are affected. var/list/attackby_types = list() - proc/allow_attackby(var/obj/item/I as obj,var/mob/user as mob) + proc/allow_attackby(var/obj/item/I as obj,var/mob/user as mob, params) for(var/typekey in attackby_types) if(istype(I,typekey)) @@ -60,7 +60,7 @@ return ..() - attackby(obj/I as obj,mob/user as mob) + attackby(obj/I as obj,mob/user as mob, params) if(computer && !computer.stat) if(istype(I, /obj/item/device/aicard)) I:transfer_ai("AIFIXER","AICARD",src,user) @@ -85,7 +85,16 @@ var/dualslot = 0 // faster than typechecking attackby_types = list(/obj/item/weapon/card) - attackby(var/obj/item/I as obj, var/mob/user as mob) + emag_act(user as mob) + if(!writer) + usr << "You insert \the card, and the computer grinds, sparks, and beeps. After a moment, the card ejects itself." + computer.emagged = 1 + return 1 + else + usr << "You are unable to insert \the card, as the reader slot is occupied" + return 0 + + attackby(var/obj/item/I as obj, var/mob/user as mob, params) if(istype(I,/obj/item/weapon/card)) insert(I) return @@ -102,14 +111,6 @@ usr << "This device has only one card slot" return 0 - if(istype(card,/obj/item/weapon/card/emag)) // emag reader slot - if(!writer) - usr << "You insert \the [card], and the computer grinds, sparks, and beeps. After a moment, the card ejects itself." - computer.emagged = 1 - return 1 - else - usr << "You are unable to insert \the [card], as the reader slot is occupied" - var/mob/living/L = usr switch(slot) if(1) @@ -132,7 +133,6 @@ else usr << "There is already something in the reader slot." - // Usage of insert() preferred, as it also tells result to the user. proc/equip_to_reader(var/obj/item/weapon/card/card, var/mob/living/L) if(!reader) diff --git a/code/modules/computer3/computer.dm b/code/modules/computer3/computer.dm index 456bdf3d71f..9ea3bff1b36 100644 --- a/code/modules/computer3/computer.dm +++ b/code/modules/computer3/computer.dm @@ -68,7 +68,7 @@ // the comms computer, solar trackers, etc, that should function when all else is off. // Laptops will require batteries and have no mains power. - var/obj/item/weapon/cell/battery = null // uninterruptible power supply aka battery + var/obj/item/weapon/stock_parts/cell/battery = null // uninterruptible power supply aka battery verb/ResetComputer() @@ -185,7 +185,7 @@ toybox.init(src) continue - if(ispath(typekey,/obj/item/weapon/cell)) + if(ispath(typekey,/obj/item/weapon/stock_parts/cell)) if(battery) continue battery = new typekey(src) continue @@ -317,7 +317,7 @@ if(os) os.error = BUSTED_ASS_COMPUTER - attackby(I as obj, mob/user as mob) + attackby(I as obj, mob/user as mob, params) if(istype(I, /obj/item/weapon/screwdriver) && allow_disassemble) disassemble(user) return @@ -341,7 +341,7 @@ P = input(user,"Which component?") as null|anything in p_list if(P) - P.attackby(I,user) + P.attackby(I,user, params) return ..() @@ -452,7 +452,7 @@ //Returns percentage of battery charge remaining. Returns -1 if no battery is installed. proc/check_battery_status() if (battery) - var/obj/item/weapon/cell/B = battery + var/obj/item/weapon/stock_parts/cell/B = battery return round(B.charge / (B.maxcharge / 100)) else return -1 diff --git a/code/modules/computer3/computers/HolodeckControl.dm b/code/modules/computer3/computers/HolodeckControl.dm index e650185f855..d53946fa12c 100644 --- a/code/modules/computer3/computers/HolodeckControl.dm +++ b/code/modules/computer3/computers/HolodeckControl.dm @@ -154,7 +154,7 @@ if(isobj(obj)) var/mob/M = obj.loc if(ismob(M)) - M.u_equip(obj) + M.unEquip(obj) M.update_icons() //so their overlays update if(!silent) diff --git a/code/modules/computer3/computers/camera.dm b/code/modules/computer3/computers/camera.dm index e0d485e1da1..ddf583888fd 100644 --- a/code/modules/computer3/computers/camera.dm +++ b/code/modules/computer3/computers/camera.dm @@ -185,12 +185,12 @@ return null var/list/L = list() - for(var/obj/machinery/camera/C in cameranet.viewpoints) + for(var/obj/machinery/camera/C in cameranet.cameras) var/list/temp = C.network & key.networks if(temp.len) L.Add(C) - camera_sort(L) + cameranet.process_sort() return L verify_machine(var/obj/machinery/camera/C,var/datum/file/camnet_key/key = null) diff --git a/code/modules/computer3/computers/card.dm b/code/modules/computer3/computers/card.dm index 7c928d2ebec..5c4a92f3227 100644 --- a/code/modules/computer3/computers/card.dm +++ b/code/modules/computer3/computers/card.dm @@ -304,7 +304,7 @@ if(auth) var/t1 = href_list["assign"] if(t1 == "Custom") - var/temp_t = copytext(sanitize(input("Enter a custom job assignment.","Assignment")),1,MAX_MESSAGE_LEN) + var/temp_t = sanitize(copytext(input("Enter a custom job assignment.","Assignment"),1,MAX_MESSAGE_LEN)) if(temp_t) t1 = temp_t set_default_access(t1) diff --git a/code/modules/computer3/computers/communications.dm b/code/modules/computer3/computers/communications.dm index 58c7f904f06..dd22bde09ec 100644 --- a/code/modules/computer3/computers/communications.dm +++ b/code/modules/computer3/computers/communications.dm @@ -42,6 +42,12 @@ var/status_display_freq = "1435" var/stat_msg1 var/stat_msg2 + + var/datum/announcement/priority/crew_announcement = new + + New() + ..() + crew_announcement.newscast = 1 Reset() ..() @@ -53,7 +59,7 @@ Topic(var/href, var/list/href_list) if(!interactable() || !computer.radio || ..(href,href_list) ) return - if (computer.z > 1) + if (!(computer.z in config.station_levels)) usr << "\red Unable to establish a connection: \black You're too far away from the station!" return @@ -68,11 +74,11 @@ authenticated = 1 if(access_captain in I.GetAccess()) authenticated = 2 - if(istype(I,/obj/item/weapon/card/emag)) - authenticated = 2 - computer.emagged = 1 + crew_announcement.announcer = GetNameAndAssignmentFromId(I) + if("logout" in href_list) authenticated = 0 + crew_announcement.announcer = "" if("swipeidseclevel" in href_list) var/mob/M = usr @@ -104,13 +110,13 @@ usr << "You need to swipe your ID." if("announce" in href_list) if(authenticated==2) - if(message_cooldown) return - var/input = stripped_input(usr, "Please choose a message to announce to the station crew.", "What?") + if(message_cooldown) + usr << "Please allow at least one minute to pass between announcements" + return + var/input = input(usr, "Please write a message to announce to the station crew.", "Priority Announcement") if(!input || !interactable()) return - captain_announce(input)//This should really tell who is, IE HoP, CE, HoS, RD, Captain - log_say("[key_name(usr)] has made a captain announcement: [input]") - message_admins("[key_name_admin(usr)] has made a captain announcement.", 1) + crew_announcement.Announce(input) message_cooldown = 1 spawn(600)//One minute cooldown message_cooldown = 0 diff --git a/code/modules/computer3/computers/law.dm b/code/modules/computer3/computers/law.dm index 409552cc79a..3d0cd0eb23e 100644 --- a/code/modules/computer3/computers/law.dm +++ b/code/modules/computer3/computers/law.dm @@ -24,7 +24,7 @@ return - attackby(obj/item/weapon/aiModule/module as obj, mob/user as mob) + attackby(obj/item/weapon/aiModule/module as obj, mob/user as mob, params) if (user.z > 6) user << "\red Unable to establish a connection: \black You're too far away from the station!" return @@ -60,7 +60,7 @@ var/mob/living/silicon/robot/current = null - attackby(obj/item/weapon/aiModule/module as obj, mob/user as mob) + attackby(obj/item/weapon/aiModule/module as obj, mob/user as mob, params) if(istype(module, /obj/item/weapon/aiModule)) module.install(src) else diff --git a/code/modules/computer3/computers/medical.dm b/code/modules/computer3/computers/medical.dm index 7fc5da12326..af2a3340ae3 100644 --- a/code/modules/computer3/computers/medical.dm +++ b/code/modules/computer3/computers/medical.dm @@ -263,7 +263,7 @@ switch(href_list["field"]) if("fingerprint") if (istype(src.active1, /datum/data/record)) - var/t1 = copytext(sanitize(input("Please input fingerprint hash:", "Med. records", src.active1.fields["fingerprint"], null) as text),1,MAX_MESSAGE_LEN) + var/t1 = trim(sanitize(copytext(input("Please input fingerprint hash:", "Med. records", src.active1.fields["fingerprint"], null) as text,1,MAX_MESSAGE_LEN))) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active1 != a1)) return src.active1.fields["fingerprint"] = t1 @@ -281,55 +281,55 @@ src.active1.fields["age"] = t1 if("mi_dis") if (istype(src.active2, /datum/data/record)) - var/t1 = copytext(sanitize(input("Please input minor disabilities list:", "Med. records", src.active2.fields["mi_dis"], null) as text),1,MAX_MESSAGE_LEN) + var/t1 = sanitize(copytext(input("Please input minor disabilities list:", "Med. records", src.active2.fields["mi_dis"], null) as text,1,MAX_MESSAGE_LEN)) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["mi_dis"] = t1 if("mi_dis_d") if (istype(src.active2, /datum/data/record)) - var/t1 = copytext(sanitize(input("Please summarize minor dis.:", "Med. records", src.active2.fields["mi_dis_d"], null) as message),1,MAX_MESSAGE_LEN) + var/t1 = sanitize(copytext(input("Please summarize minor dis.:", "Med. records", src.active2.fields["mi_dis_d"], null) as message,1,MAX_MESSAGE_LEN)) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["mi_dis_d"] = t1 if("ma_dis") if (istype(src.active2, /datum/data/record)) - var/t1 = copytext(sanitize(input("Please input major diabilities list:", "Med. records", src.active2.fields["ma_dis"], null) as text),1,MAX_MESSAGE_LEN) + var/t1 = sanitize(copytext(input("Please input major diabilities list:", "Med. records", src.active2.fields["ma_dis"], null) as text,1,MAX_MESSAGE_LEN)) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["ma_dis"] = t1 if("ma_dis_d") if (istype(src.active2, /datum/data/record)) - var/t1 = copytext(sanitize(input("Please summarize major dis.:", "Med. records", src.active2.fields["ma_dis_d"], null) as message),1,MAX_MESSAGE_LEN) + var/t1 = sanitize(copytext(input("Please summarize major dis.:", "Med. records", src.active2.fields["ma_dis_d"], null) as message,1,MAX_MESSAGE_LEN)) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["ma_dis_d"] = t1 if("alg") if (istype(src.active2, /datum/data/record)) - var/t1 = copytext(sanitize(input("Please state allergies:", "Med. records", src.active2.fields["alg"], null) as text),1,MAX_MESSAGE_LEN) + var/t1 = sanitize(copytext(input("Please state allergies:", "Med. records", src.active2.fields["alg"], null) as text,1,MAX_MESSAGE_LEN)) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["alg"] = t1 if("alg_d") if (istype(src.active2, /datum/data/record)) - var/t1 = copytext(sanitize(input("Please summarize allergies:", "Med. records", src.active2.fields["alg_d"], null) as message),1,MAX_MESSAGE_LEN) + var/t1 = sanitize(copytext(input("Please summarize allergies:", "Med. records", src.active2.fields["alg_d"], null) as message,1,MAX_MESSAGE_LEN)) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["alg_d"] = t1 if("cdi") if (istype(src.active2, /datum/data/record)) - var/t1 = copytext(sanitize(input("Please state diseases:", "Med. records", src.active2.fields["cdi"], null) as text),1,MAX_MESSAGE_LEN) + var/t1 = sanitize(copytext(input("Please state diseases:", "Med. records", src.active2.fields["cdi"], null) as text,1,MAX_MESSAGE_LEN)) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["cdi"] = t1 if("cdi_d") if (istype(src.active2, /datum/data/record)) - var/t1 = copytext(sanitize(input("Please summarize diseases:", "Med. records", src.active2.fields["cdi_d"], null) as message),1,MAX_MESSAGE_LEN) + var/t1 = sanitize(copytext(input("Please summarize diseases:", "Med. records", src.active2.fields["cdi_d"], null) as message,1,MAX_MESSAGE_LEN)) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["cdi_d"] = t1 if("notes") if (istype(src.active2, /datum/data/record)) - var/t1 = copytext(html_encode(input("Please summarize notes:", "Med. records", html_decode(src.active2.fields["notes"]), null) as message),1,MAX_MESSAGE_LEN) + var/t1 = html_encode(trim(copytext(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() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["notes"] = t1 @@ -344,21 +344,21 @@ src.temp = text("Blood Type:
    \n\tA- A+
    \n\tB- B+
    \n\tAB- AB+
    \n\tO- O+
    ", src, src, src, src, src, src, src, src) if("b_dna") if (istype(src.active1, /datum/data/record)) - var/t1 = copytext(sanitize(input("Please input DNA hash:", "Med. records", src.active1.fields["dna"], null) as text),1,MAX_MESSAGE_LEN) + var/t1 = sanitize(copytext(input("Please input DNA hash:", "Med. records", src.active1.fields["dna"], null) as text,1,MAX_MESSAGE_LEN)) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active1 != a1)) return src.active1.fields["dna"] = t1 if("vir_name") var/datum/data/record/v = locate(href_list["edit_vir"]) if (v) - var/t1 = copytext(sanitize(input("Please input pathogen name:", "VirusDB", v.fields["name"], null) as text),1,MAX_MESSAGE_LEN) + var/t1 = sanitize(copytext(input("Please input pathogen name:", "VirusDB", v.fields["name"], null) as text,1,MAX_MESSAGE_LEN)) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active1 != a1)) return v.fields["name"] = t1 if("vir_desc") var/datum/data/record/v = locate(href_list["edit_vir"]) if (v) - var/t1 = copytext(sanitize(input("Please input information about pathogen:", "VirusDB", v.fields["description"], null) as message),1,MAX_MESSAGE_LEN) + var/t1 = sanitize(copytext(input("Please input information about pathogen:", "VirusDB", v.fields["description"], null) as message,1,MAX_MESSAGE_LEN)) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active1 != a1)) return v.fields["description"] = t1 @@ -461,7 +461,7 @@ if (!( istype(src.active2, /datum/data/record) )) return var/a2 = src.active2 - var/t1 = copytext(sanitize(input("Add Comment:", "Med. records", null, null) as message),1,MAX_MESSAGE_LEN) + var/t1 = sanitize(copytext(input("Add Comment:", "Med. records", null, null) as message,1,MAX_MESSAGE_LEN)) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return var/counter = 1 diff --git a/code/modules/computer3/computers/message.dm b/code/modules/computer3/computers/message.dm index 3bbb580f5e9..3eab3f59269 100644 --- a/code/modules/computer3/computers/message.dm +++ b/code/modules/computer3/computers/message.dm @@ -383,7 +383,7 @@ //Enter message if("Message") custommessage = input(usr, "Please enter your message.") as text|null - custommessage = copytext(sanitize(custommessage), 1, MAX_MESSAGE_LEN) + custommessage = sanitize(copytext(custommessage), 1, MAX_MESSAGE_LEN) //Send message if("Send") diff --git a/code/modules/computer3/computers/prisoner.dm b/code/modules/computer3/computers/prisoner.dm index 11aa5ebd6e9..4bb238852fc 100644 --- a/code/modules/computer3/computers/prisoner.dm +++ b/code/modules/computer3/computers/prisoner.dm @@ -90,7 +90,7 @@ screen = !screen else if(href_list["warn"]) - var/warning = trim(copytext(sanitize(input(usr,"Message:","Enter your message here!","")),1,MAX_MESSAGE_LEN)) + var/warning = trim(sanitize(copytext(input(usr,"Message:","Enter your message here!",""),1,MAX_MESSAGE_LEN))) if(!warning) return var/obj/item/weapon/implant/I = locate(href_list["warn"]) if( istype(I) && I.imp_in) diff --git a/code/modules/computer3/computers/prisonshuttle.dm b/code/modules/computer3/computers/prisonshuttle.dm index f6f246e5784..e091c4dd5f5 100644 --- a/code/modules/computer3/computers/prisonshuttle.dm +++ b/code/modules/computer3/computers/prisonshuttle.dm @@ -22,7 +22,7 @@ var/prison_shuttle_timeleft = 0 var/prison_break = 0 - attackby(I as obj, user as mob) + attackby(I as obj, user as mob, params) return src.attack_hand(user) @@ -34,7 +34,7 @@ var/prison_shuttle_timeleft = 0 return src.attack_hand(user) - attackby(I as obj, user as mob) + attackby(I as obj, user as mob, params) if(istype(I, /obj/item/tool/screwdriver)) playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) if(do_after(user, 20)) diff --git a/code/modules/computer3/computers/security.dm b/code/modules/computer3/computers/security.dm index f193b071396..cccfaca2d6e 100644 --- a/code/modules/computer3/computers/security.dm +++ b/code/modules/computer3/computers/security.dm @@ -38,7 +38,7 @@ proc/authenticate() - if(access_security in scan.access || access_forensics_lockers in scan.access ) + if((access_security in scan.access) || (access_forensics_lockers in scan.access) ) return 1 if(istype(usr,/mob/living/silicon/ai)) return 1 @@ -404,7 +404,7 @@ What a mess.*/ if (!( istype(active2, /datum/data/record) )) return var/a2 = active2 - var/t1 = copytext(sanitize(input("Add Comment:", "Secure. records", null, null) as message),1,MAX_MESSAGE_LEN) + var/t1 = sanitize(copytext(input("Add Comment:", "Secure. records", null, null) as message,1,MAX_MESSAGE_LEN)) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active2 != a2)) return var/counter = 1 @@ -473,13 +473,13 @@ What a mess.*/ active1.fields["name"] = t1 if("id") if (istype(active2, /datum/data/record)) - var/t1 = copytext(sanitize(input("Please input id:", "Secure. records", active1.fields["id"], null) as text),1,MAX_MESSAGE_LEN) + var/t1 = sanitize(copytext(input("Please input id:", "Secure. records", active1.fields["id"], null) as text,1,MAX_MESSAGE_LEN)) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active1 != a1)) return active1.fields["id"] = t1 if("fingerprint") if (istype(active1, /datum/data/record)) - var/t1 = copytext(sanitize(input("Please input fingerprint hash:", "Secure. records", active1.fields["fingerprint"], null) as text),1,MAX_MESSAGE_LEN) + var/t1 = sanitize(copytext(input("Please input fingerprint hash:", "Secure. records", active1.fields["fingerprint"], null) as text,1,MAX_MESSAGE_LEN)) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active1 != a1)) return active1.fields["fingerprint"] = t1 @@ -497,31 +497,31 @@ What a mess.*/ active1.fields["age"] = t1 if("mi_crim") if (istype(active2, /datum/data/record)) - var/t1 = copytext(sanitize(input("Please input minor disabilities list:", "Secure. records", active2.fields["mi_crim"], null) as text),1,MAX_MESSAGE_LEN) + var/t1 = sanitize(copytext(input("Please input minor disabilities list:", "Secure. records", active2.fields["mi_crim"], null) as text,1,MAX_MESSAGE_LEN)) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active2 != a2)) return active2.fields["mi_crim"] = t1 if("mi_crim_d") if (istype(active2, /datum/data/record)) - var/t1 = copytext(sanitize(input("Please summarize minor dis.:", "Secure. records", active2.fields["mi_crim_d"], null) as message),1,MAX_MESSAGE_LEN) + var/t1 = sanitize(copytext(input("Please summarize minor dis.:", "Secure. records", active2.fields["mi_crim_d"], null) as message,1,MAX_MESSAGE_LEN)) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active2 != a2)) return active2.fields["mi_crim_d"] = t1 if("ma_crim") if (istype(active2, /datum/data/record)) - var/t1 = copytext(sanitize(input("Please input major diabilities list:", "Secure. records", active2.fields["ma_crim"], null) as text),1,MAX_MESSAGE_LEN) + var/t1 = sanitize(copytext(input("Please input major diabilities list:", "Secure. records", active2.fields["ma_crim"], null) as text,1,MAX_MESSAGE_LEN)) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active2 != a2)) return active2.fields["ma_crim"] = t1 if("ma_crim_d") if (istype(active2, /datum/data/record)) - var/t1 = copytext(sanitize(input("Please summarize major dis.:", "Secure. records", active2.fields["ma_crim_d"], null) as message),1,MAX_MESSAGE_LEN) + var/t1 = sanitize(copytext(input("Please summarize major dis.:", "Secure. records", active2.fields["ma_crim_d"], null) as message,1,MAX_MESSAGE_LEN)) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active2 != a2)) return active2.fields["ma_crim_d"] = t1 if("notes") if (istype(active2, /datum/data/record)) - var/t1 = copytext(html_encode(input("Please summarize notes:", "Secure. records", html_decode(active2.fields["notes"]), null) as message),1,MAX_MESSAGE_LEN) + var/t1 = trim(sanitize(copytext(input("Please summarize minor dis.:", "Secure. records", active2.fields["mi_crim_d"], null) as message,1,MAX_MESSAGE_LEN))) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active2 != a2)) return active2.fields["notes"] = t1 @@ -548,7 +548,7 @@ What a mess.*/ alert(usr, "You do not have the required rank to do this!") if("species") if (istype(active1, /datum/data/record)) - var/t1 = copytext(sanitize(input("Please enter race:", "General records", active1.fields["species"], null) as message),1,MAX_MESSAGE_LEN) + var/t1 = sanitize(copytext(input("Please enter race:", "General records", active1.fields["species"], null) as message,1,MAX_MESSAGE_LEN)) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active1 != a1)) return active1.fields["species"] = t1 diff --git a/code/modules/computer3/computers/shuttle.dm b/code/modules/computer3/computers/shuttle.dm index 5d5fab6528b..37c5291bada 100644 --- a/code/modules/computer3/computers/shuttle.dm +++ b/code/modules/computer3/computers/shuttle.dm @@ -11,7 +11,7 @@ var/list/authorized = list( ) - attackby(var/obj/item/card/W as obj, var/mob/user as mob) + attackby(var/obj/item/card/W as obj, var/mob/user as mob, params) if(stat & (BROKEN|NOPOWER)) return if ((!( istype(W, /obj/item/card) ) || !( ticker ) || emergency_shuttle.location != 1 || !( user ))) return if (istype(W, /obj/item/card/id)||istype(W, /obj/item/device/pda)) @@ -60,11 +60,13 @@ world << "\blue All authorizations to shorting time for shuttle launch have been revoked!" src.authorized.len = 0 src.authorized = list( ) - - else if (istype(W, /obj/item/card/emag) && !emagged) + return + + emag_act(user as mob) + if (!emagged) var/choice = alert(user, "Would you like to launch the shuttle?","Shuttle control", "Launch", "Cancel") - if(!emagged && emergency_shuttle.location == 1 && user.get_active_hand() == W) + if(!emagged && emergency_shuttle.location == 1) switch(choice) if("Launch") world << "\blue Alert: Shuttle launch time shortened to 10 seconds!" @@ -72,4 +74,3 @@ emagged = 1 if("Cancel") return - return diff --git a/code/modules/computer3/computers/specops_shuttle.dm b/code/modules/computer3/computers/specops_shuttle.dm index 81c94614cf0..409246b9c8a 100644 --- a/code/modules/computer3/computers/specops_shuttle.dm +++ b/code/modules/computer3/computers/specops_shuttle.dm @@ -159,7 +159,7 @@ var/specops_shuttle_timeleft = 0 if(specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom) return 0 else return 1 -/obj/machinery/computer3/specops_shuttle/attackby(I as obj, user as mob) +/obj/machinery/computer3/specops_shuttle/attackby(I as obj, user as mob, params) return attack_hand(user) /obj/machinery/computer3/specops_shuttle/attack_ai(var/mob/user as mob) @@ -168,7 +168,7 @@ var/specops_shuttle_timeleft = 0 /obj/machinery/computer3/specops_shuttle/attack_paw(var/mob/user as mob) return attack_hand(user) -/obj/machinery/computer3/specops_shuttle/attackby(I as obj, user as mob) +/obj/machinery/computer3/specops_shuttle/attackby(I as obj, user as mob, params) if(istype(I,/obj/item/card/emag)) user << "\blue The electronic systems in this console are far too advanced for your primitive hacking peripherals." else diff --git a/code/modules/computer3/computers/syndicate_shuttle.dm b/code/modules/computer3/computers/syndicate_shuttle.dm index ccd711788b3..1b4d35456c7 100644 --- a/code/modules/computer3/computers/syndicate_shuttle.dm +++ b/code/modules/computer3/computers/syndicate_shuttle.dm @@ -36,7 +36,7 @@ return 1 -/obj/machinery/computer3/syndicate_station/attackby(obj/item/I as obj, mob/user as mob) +/obj/machinery/computer3/syndicate_station/attackby(obj/item/I as obj, mob/user as mob, params) return attack_hand(user) /obj/machinery/computer3/syndicate_station/attack_ai(mob/user as mob) diff --git a/code/modules/computer3/computers/syndicate_specops_shuttle.dm b/code/modules/computer3/computers/syndicate_specops_shuttle.dm index 61dc0ba975b..2e9b4bc1842 100644 --- a/code/modules/computer3/computers/syndicate_specops_shuttle.dm +++ b/code/modules/computer3/computers/syndicate_specops_shuttle.dm @@ -172,7 +172,7 @@ var/syndicate_elite_shuttle_timeleft = 0 if(syndicate_elite_shuttle_moving_to_station || syndicate_elite_shuttle_moving_to_mothership) return 0 else return 1 -/obj/machinery/computer3/syndicate_elite_shuttle/attackby(I as obj, user as mob) +/obj/machinery/computer3/syndicate_elite_shuttle/attackby(I as obj, user as mob, params) return attack_hand(user) /obj/machinery/computer3/syndicate_elite_shuttle/attack_ai(var/mob/user as mob) @@ -181,7 +181,7 @@ var/syndicate_elite_shuttle_timeleft = 0 /obj/machinery/computer3/syndicate_elite_shuttle/attack_paw(var/mob/user as mob) return attack_hand(user) -/obj/machinery/computer3/syndicate_elite_shuttle/attackby(I as obj, user as mob) +/obj/machinery/computer3/syndicate_elite_shuttle/attackby(I as obj, user as mob, params) if(istype(I,/obj/item/card/emag)) user << "\blue The electronic systems in this console are far too advanced for your primitive hacking peripherals." else diff --git a/code/modules/computer3/laptop.dm b/code/modules/computer3/laptop.dm index 819036c6df5..bd45c044748 100644 --- a/code/modules/computer3/laptop.dm +++ b/code/modules/computer3/laptop.dm @@ -122,7 +122,7 @@ New(var/L, var/built = 0) if(!built && !battery) - battery = new /obj/item/weapon/cell(src) + battery = new /obj/item/weapon/stock_parts/cell(src) ..(L,built) verb/close_computer() diff --git a/code/modules/computer3/lapvend.dm b/code/modules/computer3/lapvend.dm index 7d9b14da7ef..4188e3a55e8 100644 --- a/code/modules/computer3/lapvend.dm +++ b/code/modules/computer3/lapvend.dm @@ -37,7 +37,7 @@ return -/obj/machinery/lapvend/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/lapvend/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(vendmode == 1) if(istype(W, /obj/item/weapon/card)) var/obj/item/weapon/card/I = W @@ -202,10 +202,10 @@ newlap.spawn_parts += (/obj/item/part/computer/networking/cable) if (power == 1) del(newlap.battery) - newlap.battery = new /obj/item/weapon/cell/high(newlap) + newlap.battery = new /obj/item/weapon/stock_parts/cell/high(newlap) if (power == 2) del(newlap.battery) - newlap.battery = new /obj/item/weapon/cell/super(newlap) + newlap.battery = new /obj/item/weapon/stock_parts/cell/super(newlap) newlap.spawn_parts() @@ -293,7 +293,7 @@ return total /obj/machinery/lapvend/proc/choose_progs(var/obj/item/weapon/card/id/C) - if(access_security in C.access || access_forensics_lockers in C.access) + if((access_security in C.access) || (access_forensics_lockers in C.access)) newlap.spawn_files += (/datum/file/program/secure_data) newlap.spawn_files += (/datum/file/camnet_key) newlap.spawn_files += (/datum/file/camnet_key/researchoutpost) @@ -349,9 +349,9 @@ network = 2 if(istype(L.stored_computer.net,/obj/item/part/computer/networking/cable)) network = 3 - if(istype(L.stored_computer.battery, /obj/item/weapon/cell/high)) + if(istype(L.stored_computer.battery, /obj/item/weapon/stock_parts/cell/high)) power = 1 - if(istype(L.stored_computer.battery, /obj/item/weapon/cell/super)) + if(istype(L.stored_computer.battery, /obj/item/weapon/stock_parts/cell/super)) power = 2 diff --git a/code/modules/computer3/program.dm b/code/modules/computer3/program.dm index 74083b8ffde..e7c1afd082f 100644 --- a/code/modules/computer3/program.dm +++ b/code/modules/computer3/program.dm @@ -85,7 +85,7 @@ Programs are a file that can be executed */ -/datum/file/program/proc/attackby(O as obj, user as mob) +/datum/file/program/proc/attackby(O as obj, user as mob, params) return /* diff --git a/code/modules/computer3/storage.dm b/code/modules/computer3/storage.dm index acf9a76288f..3fe8279fad7 100644 --- a/code/modules/computer3/storage.dm +++ b/code/modules/computer3/storage.dm @@ -114,7 +114,7 @@ inserted = null - attackby(obj/O as obj, mob/user as mob) + attackby(obj/O as obj, mob/user as mob, params) if(inserted && istype(O,/obj/item/weapon/pen)) usr << "You use [O] to carefully pry [inserted] out of [src]." eject_disk(forced = 1) diff --git a/code/modules/computer3/test_machines.dm b/code/modules/computer3/test_machines.dm index 998937e6344..1be6f232d61 100644 --- a/code/modules/computer3/test_machines.dm +++ b/code/modules/computer3/test_machines.dm @@ -12,7 +12,7 @@ /obj/item/part/computer/cardslot/dual,/obj/item/part/computer/networking/area) New(var/L,var/built=0) if(!built && !battery) - battery = new /obj/item/weapon/cell(src) + battery = new /obj/item/weapon/stock_parts/cell(src) ..(L,built) /obj/machinery/computer3/laptop/testing @@ -28,7 +28,7 @@ /obj/item/part/computer/cardslot/dual,/obj/item/part/computer/networking/area) New(var/L,var/built=0) if(!built && !battery) - battery = new /obj/item/weapon/cell/super(src) + battery = new /obj/item/weapon/stock_parts/cell/super(src) ..(L,built) /obj/machinery/computer3/wall_comp/testing @@ -44,7 +44,7 @@ /obj/item/part/computer/cardslot/dual,/obj/item/part/computer/networking/area) New(var/L,var/built=0) if(!built && !battery) - battery = new /obj/item/weapon/cell(src) + battery = new /obj/item/weapon/stock_parts/cell(src) ..(L,built) /obj/machinery/computer3/server/testing @@ -60,7 +60,7 @@ /obj/item/part/computer/cardslot/dual,/obj/item/part/computer/networking/area) New(var/L,var/built=0) if(!built && !battery) - battery = new /obj/item/weapon/cell(src) + battery = new /obj/item/weapon/stock_parts/cell(src) ..(L,built) /obj/machinery/computer3/server/rack/testing @@ -76,7 +76,7 @@ /obj/item/part/computer/cardslot/dual,/obj/item/part/computer/networking/area) New(var/L,var/built=0) if(!built && !battery) - battery = new /obj/item/weapon/cell(src) + battery = new /obj/item/weapon/stock_parts/cell(src) ..(L,built) /obj/item/weapon/storage/box/testing_disks diff --git a/code/modules/crafting/guncrafting.dm b/code/modules/crafting/guncrafting.dm new file mode 100644 index 00000000000..e29a1b47e64 --- /dev/null +++ b/code/modules/crafting/guncrafting.dm @@ -0,0 +1,83 @@ +// This file is for projectile weapon crafting. All parts and construction paths will be contained here. +// The weapons themselves are children of other weapons and should be contained in their respective files. + +// PARTS // + +/obj/item/weaponcrafting/receiver + name = "modular receiver" + desc = "A prototype modular receiver and trigger assembly for a firearm." + icon = 'icons/obj/improvised.dmi' + icon_state = "receiver" + +/obj/item/weaponcrafting/stock + name = "rifle stock" + desc = "A classic rifle stock that doubles as a grip, roughly carved out of wood." + icon = 'icons/obj/improvised.dmi' + icon_state = "riflestock" + + +// CRAFTING // + +/obj/item/weaponcrafting/receiver/attackby(obj/item/W as obj, mob/user as mob, params) + if(istype(W,/obj/item/pipe)) + user << "You attach the shotgun barrel to the receiver. The pins seem loose." + var/obj/item/weaponcrafting/ishotgunconstruction/I = new /obj/item/weaponcrafting/ishotgunconstruction + user.unEquip(src) + user.put_in_hands(I) + del(W) + del(src) + return + +// SHOTGUN // + +/obj/item/weaponcrafting/ishotgunconstruction + name = "slightly conspicuous metal construction" + desc = "A long pipe attached to a firearm receiver. The pins seem loose." + icon = 'icons/obj/improvised.dmi' + icon_state = "ishotgunstep1" + +/obj/item/weaponcrafting/ishotgunconstruction/attackby(var/obj/item/I, mob/user as mob, params) + ..() + if(istype(I, /obj/item/weapon/screwdriver)) + var/obj/item/weaponcrafting/ishotgunconstruction2/C = new /obj/item/weaponcrafting/ishotgunconstruction2 + user.unEquip(src) + user.put_in_hands(C) + user << "You screw the pins into place, securing the pipe to the receiver." + qdel(src) + +/obj/item/weaponcrafting/ishotgunconstruction2 + name = "very conspicuous metal construction" + desc = "A long pipe attached to a trigger assembly." + icon = 'icons/obj/improvised.dmi' + icon_state = "ishotgunstep1" + +/obj/item/weaponcrafting/ishotgunconstruction2/attackby(obj/item/W as obj, mob/user as mob, params) + if(istype(W,/obj/item/weaponcrafting/stock)) + user << "You attach the stock to the receiver-barrel assembly." + var/obj/item/weaponcrafting/ishotgunconstruction3/I = new /obj/item/weaponcrafting/ishotgunconstruction3 + user.unEquip(src) + user.put_in_hands(I) + del(W) + del(src) + return + +/obj/item/weaponcrafting/ishotgunconstruction3 + name = "extremely conspicuous metal construction" + desc = "A receiver-barrel shotgun assembly with a loose wooden stock. There's no way you can fire it without the stock coming loose." + icon = 'icons/obj/improvised.dmi' + icon_state = "ishotgunstep2" + +/obj/item/weaponcrafting/ishotgunconstruction3/attackby(var/obj/item/I, mob/user as mob, params) + ..() + if(istype(I, /obj/item/stack/packageWrap)) + var/obj/item/stack/packageWrap/C = I + if (C.use(5)) + var/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/W = new /obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised + user.unEquip(src) + user.put_in_hands(W) + user << "You tie the wrapping paper around the stock and the barrel to secure it." + qdel(src) + else + user << "You need at least five feet of wrapping paper to secure the stock." + return + diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm new file mode 100644 index 00000000000..b1eeae11fca --- /dev/null +++ b/code/modules/crafting/recipes.dm @@ -0,0 +1,138 @@ +/datum/table_recipe + var/name = "" //in-game display name + var/reqs[] = list() //type paths of items consumed associated with how many are needed + var/result //type path of item resulting from this craft + var/tools[] = list() //type paths of items needed but not consumed + var/time = 30 //time in deciseconds + var/parts[] = list() //type paths of items that will be placed in the result + var/chem_catalists[] = list() //like tools but for reagents + + +/datum/table_recipe/IED + name = "IED" + result = /obj/item/weapon/grenade/iedcasing + reqs = list(/datum/reagent/fuel = 50, + /obj/item/stack/cable_coil = 1, + /obj/item/device/assembly/igniter = 1, + /obj/item/weapon/reagent_containers/food/drinks/cans = 1) + parts = list(/obj/item/weapon/reagent_containers/food/drinks/cans = 1) + time = 80 + +/datum/table_recipe/stunprod + name = "Stunprod" + result = /obj/item/weapon/melee/baton/cattleprod + reqs = list(/obj/item/weapon/restraints/handcuffs/cable = 1, + /obj/item/stack/rods = 1, + /obj/item/weapon/wirecutters = 1, + /obj/item/weapon/stock_parts/cell = 1) + time = 80 + parts = list(/obj/item/weapon/stock_parts/cell = 1) + +/datum/table_recipe/ed209 + name = "ED209" + result = /obj/machinery/bot/ed209 + reqs = list(/obj/item/robot_parts/robot_suit = 1, + /obj/item/clothing/head/helmet = 1, + /obj/item/clothing/suit/armor/vest = 1, + /obj/item/robot_parts/l_leg = 1, + /obj/item/robot_parts/r_leg = 1, + /obj/item/stack/sheet/metal = 5, + /obj/item/stack/cable_coil = 5, + /obj/item/weapon/gun/energy/advtaser = 1, + /obj/item/weapon/stock_parts/cell = 1, + /obj/item/device/assembly/prox_sensor = 1, + /obj/item/robot_parts/r_arm = 1) + tools = list(/obj/item/weapon/weldingtool, /obj/item/weapon/screwdriver) + time = 120 + +/datum/table_recipe/secbot + name = "Secbot" + result = /obj/machinery/bot/secbot + reqs = list(/obj/item/device/assembly/signaler = 1, + /obj/item/clothing/head/helmet = 1, + /obj/item/weapon/melee/baton = 1, + /obj/item/device/assembly/prox_sensor = 1, + /obj/item/robot_parts/r_arm = 1) + tools = list(/obj/item/weapon/weldingtool) + time = 120 + +/datum/table_recipe/cleanbot + name = "Cleanbot" + result = /obj/machinery/bot/cleanbot + reqs = list(/obj/item/weapon/reagent_containers/glass/bucket = 1, + /obj/item/device/assembly/prox_sensor = 1, + /obj/item/robot_parts/r_arm = 1) + time = 80 + +/datum/table_recipe/floorbot + name = "Floorbot" + result = /obj/machinery/bot/floorbot + reqs = list(/obj/item/weapon/storage/toolbox/mechanical = 1, + /obj/item/stack/tile/plasteel = 1, + /obj/item/device/assembly/prox_sensor = 1, + /obj/item/robot_parts/r_arm = 1) + time = 80 + +/datum/table_recipe/medbot + name = "Medbot" + result = /obj/machinery/bot/medbot + reqs = list(/obj/item/device/healthanalyzer = 1, + /obj/item/weapon/storage/firstaid = 1, + /obj/item/device/assembly/prox_sensor = 1, + /obj/item/robot_parts/r_arm = 1) + time = 80 + +/datum/table_recipe/flamethrower + name = "Flamethrower" + result = /obj/item/weapon/flamethrower + reqs = list(/obj/item/weapon/weldingtool = 1, + /obj/item/device/assembly/igniter = 1, + /obj/item/stack/rods = 2) + tools = list(/obj/item/weapon/screwdriver) + time = 20 + +/datum/table_recipe/meteorshot + name = "Meteorshot Shell" + result = /obj/item/ammo_casing/shotgun/meteorshot + reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1, + /obj/item/weapon/rcd_ammo = 1, + /obj/item/weapon/stock_parts/manipulator = 2) + tools = list(/obj/item/weapon/screwdriver) + time = 5 + +/datum/table_recipe/pulseslug + name = "Pulse Slug Shell" + result = /obj/item/ammo_casing/shotgun/pulseslug + reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1, + /obj/item/weapon/stock_parts/capacitor/adv = 2, + /obj/item/weapon/stock_parts/micro_laser/ultra = 1) + tools = list(/obj/item/weapon/screwdriver) + time = 5 + +/datum/table_recipe/dragonsbreath + name = "Dragonsbreath Shell" + result = /obj/item/ammo_casing/shotgun/incendiary/dragonsbreath + reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1, + /datum/reagent/phosphorus = 5,) + tools = list(/obj/item/weapon/screwdriver) + time = 5 + +/datum/table_recipe/frag12 + name = "FRAG-12 Shell" + result = /obj/item/ammo_casing/shotgun/frag12 + reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1, + /datum/reagent/glycerol = 5, + /datum/reagent/sacid = 5, + /datum/reagent/pacid = 5,) + tools = list(/obj/item/weapon/screwdriver) + time = 5 + +/datum/table_recipe/ishotgun + name = "Improvised Shotgun" + result = /obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised + reqs = list(/obj/item/weaponcrafting/receiver = 1, + /obj/item/pipe = 1, + /obj/item/weaponcrafting/stock = 1, + /obj/item/stack/packageWrap = 5,) + tools = list(/obj/item/weapon/screwdriver) + time = 200 \ No newline at end of file diff --git a/code/modules/crafting/table.dm b/code/modules/crafting/table.dm new file mode 100644 index 00000000000..1d4bfa561e9 --- /dev/null +++ b/code/modules/crafting/table.dm @@ -0,0 +1,200 @@ +#define TABLECRAFT_MAX_ITEMS 30 + +/obj/structure/table + var/list/table_contents = list() + +/obj/structure/table/MouseDrop(atom/over) + if(over != usr) + return + interact(usr) + +/obj/structure/table/proc/check_contents(datum/table_recipe/R) + check_table() + main_loop: + for(var/A in R.reqs) + for(var/B in table_contents) + if(ispath(B, A)) + if(table_contents[B] >= R.reqs[A]) + continue main_loop + return 0 + for(var/A in R.chem_catalists) + if(table_contents[A] < R.chem_catalists[A]) + return 0 + return 1 + +/obj/structure/table/proc/check_table() + table_contents = list() + for(var/obj/item/I in loc) + if(istype(I, /obj/item/stack)) + var/obj/item/stack/S = I + table_contents[I.type] += S.amount + else + if(istype(I, /obj/item/weapon/reagent_containers)) + var/obj/item/weapon/reagent_containers/RC = I + if(RC.flags & OPENCONTAINER) + for(var/datum/reagent/A in RC.reagents.reagent_list) + table_contents[A.type] += A.volume + table_contents[I.type] += 1 + +/obj/structure/table/proc/check_tools(mob/user, datum/table_recipe/R) + if(!R.tools.len) + return 1 + var/list/possible_tools = list() + for(var/obj/item/I in user.contents) + if(istype(I, /obj/item/weapon/storage)) + for(var/obj/item/SI in I.contents) + possible_tools += SI.type + else + possible_tools += I.type + possible_tools += table_contents + var/i = R.tools.len + var/I + for(var/A in R.tools) + I = possible_tools.Find(A) + if(I) + possible_tools.Cut(I, I+1) + i-- + else + break + return !i + +/obj/structure/table/proc/construct_item(mob/user, datum/table_recipe/R) + check_table() + if(check_contents(R) && check_tools(user, R)) + if(do_after(user, R.time)) + if(!check_contents(R) || !check_tools(user, R)) + return 0 + var/atom/movable/I = new R.result (loc) + var/list/parts = del_reqs(R, I) + for(var/A in parts) + if(istype(A, /obj/item)) + var/atom/movable/B = A + B.loc = I + else + if(!I.reagents) + I.reagents = new /datum/reagents() + I.reagents.reagent_list.Add(A) + I.CheckParts() + return 1 + return 0 + +/obj/structure/table/proc/del_reqs(datum/table_recipe/R, atom/movable/resultobject) + var/list/Deletion = list() + var/amt + var/reagenttransfer = 0 + if(istype(resultobject,/obj/item/weapon/reagent_containers)) + reagenttransfer = 1 + for(var/A in R.reqs) + amt = R.reqs[A] + if(ispath(A, /obj/item/stack)) + var/obj/item/stack/S + stack_loop: + for(var/B in table_contents) + if(ispath(B, A)) + while(amt > 0) + S = locate(B) in loc + if(S.amount >= amt) + S.use(amt) + break stack_loop + else + amt -= S.amount + qdel(S) + else if(ispath(A, /obj/item)) + var/obj/item/I + item_loop: + for(var/B in table_contents) + if(ispath(B, A)) + while(amt > 0) + I = locate(B) in loc + Deletion.Add(I) + I.loc = null //remove it from the table loc so that we don't locate the same item every time (will be relocated inside the crafted item in construct_item()) + amt-- + if(reagenttransfer && istype(I,/obj/item/weapon/reagent_containers)) + var/obj/item/weapon/reagent_containers/RC = I + RC.reagents.trans_to(resultobject, RC.reagents.total_volume) + break item_loop + else + var/datum/reagent/RG = new A + reagent_loop: + for(var/B in table_contents) + if(ispath(B, /obj/item/weapon/reagent_containers)) + var/obj/item/RC = locate(B) in loc + if(RC.reagents.has_reagent(RG.id, amt)) + if(reagenttransfer) + RC.reagents.trans_id_to(resultobject,RG.id, amt) + else + RC.reagents.remove_reagent(RG.id, amt) + RG.volume = amt + Deletion.Add(RG) + break reagent_loop + else if(RC.reagents.has_reagent(RG.id)) + Deletion.Add(RG) + RG.volume += RC.reagents.get_reagent_amount(RG.id) + amt -= RC.reagents.get_reagent_amount(RG.id) + if(reagenttransfer) + RC.reagents.trans_id_to(resultobject,RG.id, RG.volume) + else + RC.reagents.del_reagent(RG.id) + + var/list/partlist = list(R.parts.len) + for(var/M in R.parts) + partlist[M] = R.parts[M] + deletion_loop: + for(var/B in Deletion) + for(var/A in R.parts) + if(istype(B, A)) + if(partlist[A] > 0) //do we still need a part like that? + partlist[A] -= 1 + continue deletion_loop + Deletion.Remove(B) + qdel(B) + + return Deletion + +/obj/structure/table/interact(mob/user) + if(user.stat || user.lying || !Adjacent(user)) + return + check_table() + if(!table_contents.len) + return + user.face_atom(src) + var/dat = "

    Crafting menu

    " + dat += "
    " + if(busy) + dat += "Crafting in progress...
    " + else + for(var/datum/table_recipe/R in table_recipes) + if(check_contents(R)) + dat += "[R.name]
    " + dat += "
" + + var/datum/browser/popup = new(user, "table", "Table", 300, 300) + popup.set_content(dat) + popup.open() + return + +/obj/structure/table/Topic(href, href_list) + if(usr.stat || !Adjacent(usr) || usr.lying) + return + if(href_list["make"]) + if(!check_table_space()) + usr << "The table is too crowded." + return + var/datum/table_recipe/TR = locate(href_list["make"]) + busy = 1 + interact(usr) + if(construct_item(usr, TR)) + usr << "[TR.name] constructed." + else + usr << "Construction failed." + busy = 0 + interact(usr) + +/obj/structure/table/proc/check_table_space() + var/Item_amount = 0 + for(var/obj/item/I in loc) + Item_amount++ + if(Item_amount <= TABLECRAFT_MAX_ITEMS) //is the table crowded? + return 1 + + #undef TABLECRAFT_MAX_ITEMS \ No newline at end of file diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index 27736fe0858..e28992cf0ba 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -18,7 +18,6 @@ icon= 'icons/obj/clothing/hats.dmi' icon_state = "hairflowerp" item_state = "hairflowerp" - flags = FPRINT|TABLEPASS /obj/item/clothing/under/fluff/WornTurtleneck // DaveTheHeadcrab: Makkota Atani name = "Worn Combat Turtleneck" @@ -46,7 +45,12 @@ name = "royal marines commando beret" desc = "Dark Green beret with an old insignia on it." icon_state = "sparkyninja_beret" - flags = FPRINT | TABLEPASS + +/obj/item/weapon/book/manual/security_space_law/black + name = "Space Law - Limited Edition" + desc = "A leather-bound, immaculately-written copy of JUSTICE." + icon_state = "bookSpaceLawblack" + title = "Space Law - Limited Edition" ////////////////////////////////// ////////// Fluff Items /////////// @@ -413,7 +417,6 @@ item_state = "ciglit" w_class = 1 body_parts_covered = null - flags = FPRINT|TABLEPASS //Strange penlight, Nerezza: Asher Spock @@ -738,7 +741,7 @@ /obj/item/clothing/under/rank/bartender/fluff/classy //searif: Ara Al-Jazari name = "classy bartender uniform" - desc = "A prim and proper uniform that looks very similar to a bartender's, the only differences being a red tie, waistcoat and a rag hanging out of the back pocket." + desc = "A prim and proper uniform that looks very similar to a bartender's, the only differences being a red accessory, waistcoat and a rag hanging out of the back pocket." icon = 'icons/obj/custom_items.dmi' icon_state = "ara_bar_uniform" item_state = "ara_bar_uniform" @@ -777,7 +780,6 @@ _color = "jane_sid_suit" has_sensor = 2 sensor_mode = 3 - flags = FPRINT | TABLEPASS //Suit roll-down toggle. /obj/item/clothing/under/fluff/jane_sidsuit/verb/toggle_zipper() @@ -818,7 +820,7 @@ icon = 'icons/obj/custom_items.dmi' icon_state = "flagmask" item_state = "flagmask" - flags = FPRINT|TABLEPASS|MASKCOVERSMOUTH + flags = MASKCOVERSMOUTH w_class = 2 gas_transfer_coefficient = 0.90 */ @@ -828,12 +830,11 @@ desc = "A silver and emerald shamrock pendant. It has the initials \"M.K.\" engraved on the back." icon = 'icons/obj/custom_items.dmi' icon_state = "mara_kilpatrick_1" - flags = FPRINT|TABLEPASS w_class = 1 ////// Small locket - Altair An-Nasaqan - Serithi -/obj/item/clothing/tie/fluff/altair_locket +/obj/item/clothing/accessory/fluff/altair_locket name = "small locket" desc = "A small golden locket attached to an Ii'rka-reed string. Inside the locket is a holo-picture of a female Tajaran, and an inscription writtin in Siik'mas." icon = 'icons/obj/custom_items.dmi' @@ -841,13 +842,12 @@ item_state = "altair_locket" _color = "altair_locket" slot_flags = 0 - flags = FPRINT|TABLEPASS w_class = 1 slot_flags = SLOT_MASK ////// Silver locket - Konaa Hirano - Konaa_Hirano -/obj/item/clothing/tie/fluff/konaa_hirano +/obj/item/clothing/accessory/fluff/konaa_hirano name = "silver locket" desc = "This oval shaped, argentium sterling silver locket hangs on an incredibly fine, refractive string, almost thin as hair and microweaved from links to a deceptive strength, of similar material. The edges are engraved very delicately with an elegant curving design, but overall the main is unmarked and smooth to the touch, leaving room for either remaining as a stolid piece or future alterations. There is an obvious internal place for a picture or lock of some sort, but even behind that is a very thin compartment unhinged with the pinch of a thumb and forefinger." icon = 'icons/obj/custom_items.dmi' @@ -855,18 +855,17 @@ item_state = "konaahirano" _color = "konaahirano" slot_flags = 0 - flags = FPRINT|TABLEPASS w_class = 1 slot_flags = SLOT_MASK var/obj/item/held //Item inside locket. -/obj/item/clothing/tie/fluff/konaa_hirano/attack_self(mob/user as mob) +/obj/item/clothing/accessory/fluff/konaa_hirano/attack_self(mob/user as mob) if(held) user << "You open [src] and [held] falls out." held.loc = get_turf(user) src.held = null -/obj/item/clothing/tie/fluff/konaa_hirano/attackby(var/obj/item/O as obj, mob/user as mob) +/obj/item/clothing/accessory/fluff/konaa_hirano/attackby(var/obj/item/O as obj, mob/user as mob, params) if(istype(O,/obj/item/weapon/paper)) if(held) usr << "[src] already has something inside it." @@ -880,24 +879,22 @@ ////// Medallion - Nasir Khayyam - Jamini -/obj/item/clothing/tie/fluff/nasir_khayyam_1 +/obj/item/clothing/accessory/fluff/nasir_khayyam_1 name = "medallion" desc = "This silvered medallion bears the symbol of the Hadii Clan of the Tajaran." icon = 'icons/obj/custom_items.dmi' icon_state = "nasir_khayyam_1" - flags = FPRINT|TABLEPASS w_class = 1 slot_flags = SLOT_MASK ////// Medallion - Lin Chang - Roland410 -/obj/item/clothing/tie/fluff/lin_chang_1 +/obj/item/clothing/accessory/fluff/lin_chang_1 name = "shining black medallion" desc = "A shiny black medallion made of something that looks like the Earth's obsidian, but it is harder than anything ever seen yet. On the front there seems to be a standing unathi chiseled in it, on the back the name of Lin Chang with the title of the Assassin Archmage." icon = 'icons/obj/custom_items.dmi' icon_state = "nasir_khayyam_1" - flags = FPRINT|TABLEPASS w_class = 1 slot_flags = SLOT_MASK @@ -908,7 +905,6 @@ desc = "A brass necklace with a green emerald placed at the end. It has a small inscription on the top of the chain, saying \'Foster\'" icon = 'icons/obj/custom_items.dmi' icon_state = "ty_foster" - flags = FPRINT|TABLEPASS w_class = 1 //////////// Shoes //////////// diff --git a/code/modules/destilery/main.dm b/code/modules/destilery/main.dm index e6944724aaf..808b74411c9 100644 --- a/code/modules/destilery/main.dm +++ b/code/modules/destilery/main.dm @@ -56,9 +56,9 @@ del(milled_item) busy = 0 -/obj/machinery/mill/attackby(var/obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/mill/attackby(var/obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/reagent_containers/food)) - user.u_equip(W) + user.unEquip(W) W.loc = src input += W else @@ -126,9 +126,9 @@ del(fermenting_item) busy = 0 -/obj/machinery/fermenter/attackby(var/obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/fermenter/attackby(var/obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/reagent_containers/food)) - user.u_equip(W) + user.unEquip(W) W.loc = src input += W else @@ -187,9 +187,9 @@ del(destilling_item) busy = 0 -/obj/machinery/still/attackby(var/obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/still/attackby(var/obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/reagent_containers/food)) - user.u_equip(W) + user.unEquip(W) W.loc = src input += W else @@ -272,9 +272,9 @@ output += spinning_item busy = 0 -/obj/machinery/centrifuge/attackby(var/obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/centrifuge/attackby(var/obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/reagent_containers/food)) - user.u_equip(W) + user.unEquip(W) W.loc = src input += W else diff --git a/code/modules/economy/ATM.dm b/code/modules/economy/ATM.dm index f389f9c2863..fad9c88110b 100644 --- a/code/modules/economy/ATM.dm +++ b/code/modules/economy/ATM.dm @@ -85,7 +85,7 @@ log transactions linked_db = DB break -/obj/machinery/atm/attackby(obj/item/I as obj, mob/user as mob) +/obj/machinery/atm/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/weapon/card)) var/obj/item/weapon/card/id/idcard = I if(!held_card) diff --git a/code/modules/economy/Accounts.dm b/code/modules/economy/Accounts.dm index 91d8662227c..018ce78cd3a 100644 --- a/code/modules/economy/Accounts.dm +++ b/code/modules/economy/Accounts.dm @@ -125,13 +125,13 @@ var/global/list/all_money_accounts = list() var/money = 0 var/suspended = 0 var/list/transaction_log = list() - var/security_level = 1 //0 - auto-identify from worn ID, require only account number + var/security_level = 0 //0 - auto-identify from worn ID, require only account number //1 - require manual login / account number and pin //2 - require card and manual login /datum/money_account/New() ..() - security_level = pick (0,1) //Stealing is now slightly viable + //security_level = pick (0,1) //Stealing is now slightly viable /datum/transaction var/target_name = "" diff --git a/code/modules/economy/Accounts_DB.dm b/code/modules/economy/Accounts_DB.dm index e7c16540552..ddd432d3dfc 100644 --- a/code/modules/economy/Accounts_DB.dm +++ b/code/modules/economy/Accounts_DB.dm @@ -56,7 +56,7 @@ machine_id = "[station_name()] Acc. DB #[num_financial_terminals++]" ..() -/obj/machinery/account_database/attackby(obj/O, mob/user) +/obj/machinery/account_database/attackby(obj/O, mob/user, params) if(!istype(O, /obj/item/weapon/card/id)) return ..() diff --git a/code/modules/economy/EFTPOS.dm b/code/modules/economy/EFTPOS.dm index b0a412bfa12..a6c8a3e74a4 100644 --- a/code/modules/economy/EFTPOS.dm +++ b/code/modules/economy/EFTPOS.dm @@ -100,7 +100,7 @@ else user << browse(null,"window=eftpos") -/obj/item/device/eftpos/attackby(O as obj, user as mob) +/obj/item/device/eftpos/attackby(O as obj, user as mob, params) if(istype(O, /obj/item/weapon/card)) //attempt to connect to a new db, and if that doesn't work then fail if(!linked_db) diff --git a/code/modules/economy/Economy.dm b/code/modules/economy/Economy.dm index cf78723a683..b41a080d251 100644 --- a/code/modules/economy/Economy.dm +++ b/code/modules/economy/Economy.dm @@ -67,7 +67,15 @@ var/setup_economy = 0 /proc/setup_economy() if(setup_economy) return + var/datum/feed_channel/newChannel = new /datum/feed_channel + newChannel.channel_name = "Public Station Announcements" + newChannel.author = "Automated Announcement Listing" + newChannel.locked = 1 + newChannel.is_admin_channel = 1 + news_network.network_channels += newChannel + + newChannel = new /datum/feed_channel newChannel.channel_name = "Tau Ceti Daily" newChannel.author = "CentComm Minister of Information" newChannel.locked = 1 diff --git a/code/modules/economy/POS.dm b/code/modules/economy/POS.dm index d4bbbb9abaa..7b1c885ff10 100644 --- a/code/modules/economy/POS.dm +++ b/code/modules/economy/POS.dm @@ -482,7 +482,7 @@ var/const/POS_HEADER = {" products[pid]=LI src.attack_hand(usr) -/obj/machinery/pos/attackby(var/atom/movable/A, var/mob/user) +/obj/machinery/pos/attackby(var/atom/movable/A, var/mob/user, params) if(istype(A,/obj/item/weapon/card/id)) var/obj/item/weapon/card/id/I = A if(!logged_in) diff --git a/code/modules/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm index a86219ba03a..b69a656ca1d 100644 --- a/code/modules/events/alien_infestation.dm +++ b/code/modules/events/alien_infestation.dm @@ -15,18 +15,17 @@ /datum/event/alien_infestation/announce() if(successSpawn) - command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert") - world << sound('sound/AI/aliens.ogg') + command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg') /datum/event/alien_infestation/start() var/list/vents = list() for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world) - if(temp_vent.loc.z == 1 && !temp_vent.welded && temp_vent.network) + if((temp_vent.loc.z in config.station_levels) && !temp_vent.welded && temp_vent.network) if(temp_vent.network.normal_members.len > 50) //Stops Aliens getting stuck in small networks. See: Security, Virology vents += temp_vent - var/list/candidates = get_candidates(BE_ALIEN,ALIEN_AFK_BRACKET,"alien","Syndicate") + var/list/candidates = get_candidates(BE_ALIEN,ALIEN_AFK_BRACKET) while(spawncount > 0 && vents.len && candidates.len) var/obj/vent = pick_n_take(vents) diff --git a/code/modules/events/blob.dm b/code/modules/events/blob.dm index 9a3dc92a754..abc3fa87d48 100644 --- a/code/modules/events/blob.dm +++ b/code/modules/events/blob.dm @@ -7,8 +7,7 @@ /datum/event/blob/announce() - command_alert("Confirmed outbreak of level 7 biohazard aboard [station_name()]. Nanotrasen has issued a directive 7-10. The station is to be considered quarantined.", "Biohazard Alert") - world << sound('sound/AI/blob_confirmed.ogg') + command_announcement.Announce("Confirmed outbreak of level 7 biohazard aboard [station_name()]. Nanotrasen has issued a directive 7-10. The station is to be considered quarantined.", "Biohazard Alert", new_sound = 'sound/AI/blob_confirmed.ogg') for (var/mob/living/silicon/ai/aiPlayer in player_list) if (aiPlayer.client) @@ -39,14 +38,14 @@ /datum/event/blob/proc/announce_nuke() var/nukecode = "ERROR" for(var/obj/machinery/nuclearbomb/bomb in world) - if(bomb && bomb.r_code && bomb.z == 1) + if(bomb && bomb.r_code && (bomb.z in config.station_levels)) nukecode = bomb.r_code - command_alert("The biohazard has grown out of control and will soon reach critical mass. Activate the nuclear failsafe to maintain quarantine. The Nuclear Authentication Code is [nukecode] ", "Biohazard Alert") + command_announcement.Announce("The biohazard has grown out of control and will soon reach critical mass. Activate the nuclear failsafe to maintain quarantine. The Nuclear Authentication Code is [nukecode] ", "Biohazard Alert") set_security_level("gamma") var/obj/machinery/door/airlock/vault/V = locate(/obj/machinery/door/airlock/vault) in world - if(V && V.z == 1) + if(V && (V.z in config.station_levels)) V.locked = 0 V.update_icon() @@ -64,12 +63,11 @@ spawn(10) if(Blob || blob_cores.len) return - command_alert("The level 7 biohazard aboard [station_name()] has been eliminated. Directive 7-10 has been lifted, and the station is no longer quarantined.", "Biohazard Update") + command_announcement.Announce("The level 7 biohazard aboard [station_name()] has been eliminated. Directive 7-10 has been lifted, and the station is no longer quarantined.", "Biohazard Update") for (var/mob/living/silicon/ai/aiPlayer in player_list) if (aiPlayer.client) - var/law = "" - aiPlayer.set_zeroth_law(law) + aiPlayer.clear_zeroth_law() aiPlayer << "\red You have detected a change in your laws information:" - aiPlayer << "Laws Updated: [law]" + aiPlayer << "Laws Updated: Zeroth law removed." ..() \ No newline at end of file diff --git a/code/modules/events/borers.dm b/code/modules/events/borers.dm index 60d342628bd..14010e22fc3 100644 --- a/code/modules/events/borers.dm +++ b/code/modules/events/borers.dm @@ -12,18 +12,17 @@ /datum/event/borer_infestation/announce() if(successSpawn) - command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert") - world << sound('sound/AI/aliens.ogg') + command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg') /datum/event/borer_infestation/start() var/list/vents = list() for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world) - if(temp_vent.loc.z == 1 && !temp_vent.welded && temp_vent.network) + if((temp_vent.loc.z in config.station_levels) && !temp_vent.welded && temp_vent.network) //Stops cortical borers getting stuck in small networks. See: Security, Virology if(temp_vent.network.normal_members.len > 50) vents += temp_vent - var/list/candidates = get_candidates(BE_ALIEN,ALIEN_AFK_BRACKET,"alien","Syndicate") + var/list/candidates = get_candidates(BE_ALIEN,ALIEN_AFK_BRACKET) while(spawncount > 0 && vents.len && candidates.len) var/obj/vent = pick_n_take(vents) var/client/C = pick_n_take(candidates) diff --git a/code/modules/events/brand_intelligence.dm b/code/modules/events/brand_intelligence.dm index a2436f2ac75..4f2616e7c0f 100644 --- a/code/modules/events/brand_intelligence.dm +++ b/code/modules/events/brand_intelligence.dm @@ -8,11 +8,11 @@ var/obj/machinery/vending/originMachine /datum/event/brand_intelligence/announce() - command_alert("Rampant brand intelligence has been detected aboard [station_name()], please stand-by.", "Machine Learning Alert") + command_announcement.Announce("Rampant brand intelligence has been detected aboard [station_name()], please stand-by.", "Machine Learning Alert") /datum/event/brand_intelligence/start() for(var/obj/machinery/vending/V in machines) - if(V.z != 1) continue + if(!(V.z in config.station_levels)) continue vendingMachines.Add(V) if(!vendingMachines.len) diff --git a/code/modules/events/cargobonus.dm b/code/modules/events/cargobonus.dm index f0c84b86f54..75276615a40 100644 --- a/code/modules/events/cargobonus.dm +++ b/code/modules/events/cargobonus.dm @@ -2,7 +2,7 @@ announceWhen = 5 /datum/event/cargo_bonus/announce() - command_alert("Congratulations! [station_name()] was chosen for supply limit increase, please contact local cargo department for details!", "Supply Alert") + command_announcement.Announce("Congratulations! [station_name()] was chosen for a supply limit increase. Please contact the local cargo department for details!", "Supply Alert") /datum/event/cargo_bonus/start() - supply_controller.points+=rand(100,500) \ No newline at end of file + supply_controller.points += rand(100,500) \ No newline at end of file diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm index 7cf82ff1f67..303f5686e8e 100644 --- a/code/modules/events/carp_migration.dm +++ b/code/modules/events/carp_migration.dm @@ -8,7 +8,7 @@ endWhen = rand(600,1200) /datum/event/carp_migration/announce() - command_alert("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert") + command_announcement.Announce("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert") /datum/event/carp_migration/start() for(var/obj/effect/landmark/C in landmarks_list) diff --git a/code/modules/events/comms_blackout.dm b/code/modules/events/comms_blackout.dm index 2f5cbea97b3..6b948538d5d 100644 --- a/code/modules/events/comms_blackout.dm +++ b/code/modules/events/comms_blackout.dm @@ -1,6 +1,6 @@ /proc/communications_blackout(var/silent = 1) if(!silent) - command_alert("Ionospheric anomalies detected. Temporary telecommunication failure imminent. Please contact you-BZZT") + command_announcement.Announce("Ionospheric anomalies detected. Temporary telecommunication failure imminent. Please contact you-BZZT") else // AIs will always know if there's a comm blackout, rogue AIs could then lie about comm blackouts in the future while they shutdown comms for(var/mob/living/silicon/ai/A in player_list) A << "
" diff --git a/code/modules/events/communications_blackout.dm b/code/modules/events/communications_blackout.dm index d437d85684e..d39517f5343 100644 --- a/code/modules/events/communications_blackout.dm +++ b/code/modules/events/communications_blackout.dm @@ -12,7 +12,7 @@ A << "
" if(prob(30)) //most of the time, we don't want an announcement, so as to allow AIs to fake blackouts. - command_alert(alert) + command_announcement.Announce(alert) /datum/event/communications_blackout/start() for(var/obj/machinery/telecomms/T in telecomms_list) diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index a12aa2147c5..ec4ea8b8d3a 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -3,8 +3,7 @@ oneShot = 1 /datum/event/disease_outbreak/announce() - command_alert("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert") - world << sound('sound/AI/outbreak7.ogg') + command_announcement.Announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg') /datum/event/disease_outbreak/setup() announceWhen = rand(15, 30) @@ -17,7 +16,7 @@ var/turf/T = get_turf(H) if(!T) continue - if(T.z != 1) + if(!(T.z in config.station_levels)) continue for(var/datum/disease/D in H.viruses) foundAlready = 1 diff --git a/code/modules/events/electrical_storm.dm b/code/modules/events/electrical_storm.dm index 2b9b989e5e9..a8254d02c7a 100644 --- a/code/modules/events/electrical_storm.dm +++ b/code/modules/events/electrical_storm.dm @@ -3,7 +3,7 @@ var/lightsoutRange = 25 /datum/event/electrical_storm/announce() - command_alert("An electrical storm has been detected in your area, please repair potential electronic overloads.", "Electrical Storm Alert") + command_announcement.Announce("An electrical storm has been detected in your area, please repair potential electronic overloads.", "Electrical Storm Alert") /datum/event/electrical_storm/start() var/list/epicentreList = list() diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index 2e0d771cd57..c49c4b80b02 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -123,20 +123,19 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT severity = EVENT_LEVEL_MUNDANE available_events = list( // Severity level, event name, even type, base weight, role weights, one shot, min weight, max weight. Last two only used if set and non-zero - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Nothing", /datum/event/nothing, 100), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Nothing", /datum/event/nothing, 1100), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "PDA Spam", /datum/event/pda_spam, 0, list(ASSIGNMENT_ANY = 4), 0, 25, 50), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Lotto", /datum/event/money_lotto, 0, list(ASSIGNMENT_ANY = 1), 1, 5, 15), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Hacker", /datum/event/money_hacker, 0, list(ASSIGNMENT_ANY = 4), 1, 10, 25), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Economic News", /datum/event/economic_event, 300), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Trivial News", /datum/event/trivial_news, 400), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Mundane News", /datum/event/mundane_news, 300), +// new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Economic News", /datum/event/economic_event, 300), +// new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Trivial News", /datum/event/trivial_news, 400), +// new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Mundane News", /datum/event/mundane_news, 300), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Lost Carp", /datum/event/carp_migration, 20, list(ASSIGNMENT_SECURITY = 10), 1), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Brand Intelligence",/datum/event/brand_intelligence,20, list(ASSIGNMENT_JANITOR = 25), 1), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Vermin Infestation",/datum/event/infestation, 100, list(ASSIGNMENT_JANITOR = 100)), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Wallrot", /datum/event/wallrot, 0, list(ASSIGNMENT_ENGINEER = 30, ASSIGNMENT_GARDENER = 50)), // NON-BAY EVENTS - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Cargo Bonus", /datum/event/cargo_bonus, 150), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Mass Hallucination",/datum/event/mass_hallucination,200), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Cargo Bonus", /datum/event/cargo_bonus, 100) ) /datum/event_container/moderate @@ -145,9 +144,9 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT new /datum/event_meta(EVENT_LEVEL_MODERATE, "Nothing", /datum/event/nothing, 1230), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Carp School", /datum/event/carp_migration, 100, list(ASSIGNMENT_ENGINEER = 10, ASSIGNMENT_SECURITY = 20), 1), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Rogue Drones", /datum/event/rogue_drone, 20, list(ASSIGNMENT_SECURITY = 20)), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space vines", /datum/event/spacevine, 200, list(ASSIGNMENT_ENGINEER = 10)), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space Vines", /datum/event/spacevine, 250, list(ASSIGNMENT_ENGINEER = 10)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meteor Shower", /datum/event/meteor_shower, 0, list(ASSIGNMENT_ENGINEER = 20)), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meaty Ores", /datum/event/dust/meaty, 0, list(ASSIGNMENT_ENGINEER = 20)), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meaty Ores", /datum/event/dust/meaty, 0, list(ASSIGNMENT_ENGINEER = 30)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Communication Blackout", /datum/event/communications_blackout, 500, list(ASSIGNMENT_AI = 150, ASSIGNMENT_SECURITY = 120)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Prison Break", /datum/event/prison_break, 0, list(ASSIGNMENT_SECURITY = 100)), // new /datum/event_meta(EVENT_LEVEL_MODERATE, "Grid Check", /datum/event/grid_check, 200, list(ASSIGNMENT_ENGINEER = 60)), @@ -156,18 +155,20 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT new /datum/event_meta(EVENT_LEVEL_MODERATE, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 150)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 30), 1), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ionstorm, 0, list(ASSIGNMENT_AI = 50, ASSIGNMENT_CYBORG = 50, ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_SCIENTIST = 5)), - new /datum/event_meta/alien(EVENT_LEVEL_MODERATE, "Alien Infestation", /datum/event/alien_infestation, 2.5, list(ASSIGNMENT_SECURITY = 1), 1, 0, 5), - new /datum/event_meta/ninja(EVENT_LEVEL_MODERATE, "Space Ninja", /datum/event/space_ninja, 0, list(ASSIGNMENT_SECURITY = 1), 1, 0, 5), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Borer Infestation", /datum/event/borer_infestation, 20, list(ASSIGNMENT_SECURITY = 20), 1), + new /datum/event_meta/alien(EVENT_LEVEL_MODERATE, "Alien Infestation", /datum/event/alien_infestation, 0, list(ASSIGNMENT_SECURITY = 15), 1), + new /datum/event_meta/ninja(EVENT_LEVEL_MODERATE, "Space Ninja", /datum/event/space_ninja, 0, list(ASSIGNMENT_SECURITY = 15), 1), // NON-BAY EVENTS - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space Dust", /datum/event/dust, 50, list(ASSIGNMENT_ENGINEER = 50)), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Mass Hallucination", /datum/event/mass_hallucination, 300), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space Dust", /datum/event/dust, 50, list(ASSIGNMENT_ENGINEER = 50)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Dimensional Tear", /datum/event/tear, 0, list(ASSIGNMENT_SECURITY = 25)), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Vent Clog", /datum/event/vent_clog, 250), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Wormholes", /datum/event/wormholes, 150), - - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Pyro Anomaly", /datum/event/anomaly/anomaly_pyro, 100, list(ASSIGNMENT_ENGINEER = 60)), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Vortex Anomaly", /datum/event/anomaly/anomaly_vortex, 50, list(ASSIGNMENT_ENGINEER = 25)), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Bluespace Anomaly", /datum/event/anomaly/anomaly_bluespace, 50, list(ASSIGNMENT_ENGINEER = 25)), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Flux Anomaly", /datum/event/anomaly/anomaly_flux, 50, list(ASSIGNMENT_ENGINEER = 50)), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Gravitational Anomaly", /datum/event/anomaly/anomaly_grav, 200), +// new /datum/event_meta(EVENT_LEVEL_MODERATE, "Pyro Anomaly", /datum/event/anomaly/anomaly_pyro, 100, list(ASSIGNMENT_ENGINEER = 60)), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Vortex Anomaly", /datum/event/anomaly/anomaly_vortex, 50, list(ASSIGNMENT_ENGINEER = 25)), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Bluespace Anomaly", /datum/event/anomaly/anomaly_bluespace, 50, list(ASSIGNMENT_ENGINEER = 25)), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Flux Anomaly", /datum/event/anomaly/anomaly_flux, 50, list(ASSIGNMENT_ENGINEER = 50)), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Gravitational Anomaly", /datum/event/anomaly/anomaly_grav, 200), ) /datum/event_container/major @@ -176,7 +177,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT new /datum/event_meta(EVENT_LEVEL_MAJOR, "Nothing", /datum/event/nothing, 1320), new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration", /datum/event/carp_migration, 0, list(ASSIGNMENT_SECURITY = 3), 1), new /datum/event_meta(EVENT_LEVEL_MAJOR, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 30), 1), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 60), 1), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 30), 1), new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 3), 1), ) diff --git a/code/modules/events/event_dynamic.dm b/code/modules/events/event_dynamic.dm index df494ddc245..a7aad12c5bb 100644 --- a/code/modules/events/event_dynamic.dm +++ b/code/modules/events/event_dynamic.dm @@ -46,8 +46,8 @@ var/global/list/possibleEvents = list() // Code/WorkInProgress/Cael_Aislinn/Economy/Economy_Events_Mundane.dm possibleEvents[/datum/event/economic_event] = 300 - possibleEvents[/datum/event/trivial_news] = 400 - possibleEvents[/datum/event/mundane_news] = 300 + //possibleEvents[/datum/event/trivial_news] = 400 + //possibleEvents[/datum/event/mundane_news] = 300 possibleEvents[/datum/event/cargo_bonus] = 150 @@ -75,11 +75,12 @@ var/global/list/possibleEvents = list() // possibleEvents[/datum/event/grid_check] = 25 + 10 * active_with_role["Engineer"] possibleEvents[/datum/event/electrical_storm] = 15 * active_with_role["Janitor"] + 5 * active_with_role["Engineer"] possibleEvents[/datum/event/wallrot] = 30 * active_with_role["Engineer"] + 50 * active_with_role["Botanist"] + possibleEvents[/datum/event/borer_infestation] = 50 + 15 * active_with_role["Security"] if(!spacevines_spawned) possibleEvents[/datum/event/spacevine] = 10 + 5 * active_with_role["Engineer"] if(minutes_passed >= 30) // Give engineers time to set up engine - possibleEvents[/datum/event/anomaly/anomaly_pyro] = 100 + 60 * active_with_role["Engineer"] +// possibleEvents[/datum/event/anomaly/anomaly_pyro] = 100 + 60 * active_with_role["Engineer"] possibleEvents[/datum/event/anomaly/anomaly_vortex] = 50 + 25 * active_with_role["Engineer"] possibleEvents[/datum/event/anomaly/anomaly_bluespace] = 50 + 25 * active_with_role["Engineer"] possibleEvents[/datum/event/anomaly/anomaly_flux] = 50 + 50 * active_with_role["Engineer"] @@ -152,10 +153,7 @@ var/global/list/possibleEvents = list() /*switch(picked_event) if("Meteor") - command_alert("Meteors have been detected on collision course with the station.", "Meteor Alert") - for(var/mob/M in player_list) - if(!istype(M,/mob/new_player)) - M << sound('sound/AI/meteors.ogg') + command_announcement.Announce("Meteors have been detected on collision course with the station.", "Meteor Alert", new_sound = 'sound/AI/meteors.ogg') spawn(100) meteor_wave(10) spawn_meteors() diff --git a/code/modules/events/event_manager.dm b/code/modules/events/event_manager.dm index caff07fb8cc..08614d68c9c 100644 --- a/code/modules/events/event_manager.dm +++ b/code/modules/events/event_manager.dm @@ -3,6 +3,7 @@ var/window_y = 600 var/report_at_round_end = 0 var/table_options = " align='center'" + var/head_options = " style='font-weight:bold;'" var/row_options1 = " width='85px'" var/row_options2 = " width='260px'" var/row_options3 = " width='150px'" @@ -87,7 +88,7 @@ html += "
" html += "

Available [severity_to_string[selected_event_container.severity]] Events (queued & running events will not be displayed)

" html += "" - html += "Name Weight MinWeight MaxWeight OneShot Enabled CurrWeight Remove" + html += "Name Weight MinWeight MaxWeight OneShot Enabled CurrWeight Remove" for(var/datum/event_meta/EM in selected_event_container.available_events) html += "" html += "[EM.name]" @@ -105,7 +106,7 @@ html += "
" html += "

Add Event

" html += "" - html += "NameTypeWeightOneShot" + html += "NameTypeWeightOneShot" html += "" html += "[new_event.name ? new_event.name : "Enter Event"]" html += "[new_event.event_type ? new_event.event_type : "Select Type"]" @@ -121,7 +122,7 @@ html += "

Event Start

" html += "" - html += "SeverityStarts AtStarts InAdjust StartPauseInterval Mod" + html += "SeverityStarts AtStarts InAdjust StartPauseInterval Mod" for(var/severity = EVENT_LEVEL_MUNDANE to EVENT_LEVEL_MAJOR) var/datum/event_container/EC = event_containers[severity] var/next_event_at = max(0, EC.next_event_time - world.time) @@ -148,7 +149,7 @@ html += "
" html += "

Next Event

" html += "" - html += "SeverityNameEvent RotationClear" + html += "SeverityNameEvent RotationClear" for(var/severity = EVENT_LEVEL_MUNDANE to EVENT_LEVEL_MAJOR) var/datum/event_container/EC = event_containers[severity] var/datum/event_meta/EM = EC.next_event @@ -165,7 +166,7 @@ html += "

Running Events

" html += "Estimated times, affected by master controller delays." html += "" - html += "SeverityNameEnds AtEnds InStop" + html += "SeverityNameEnds AtEnds InStop" for(var/datum/event/E in active_events) if(!E.event_meta) continue @@ -292,12 +293,12 @@ /client/proc/event_manager_panel() set name = "Event Manager Panel" - set category = "Admin" + set category = "Event" if(event_manager) event_manager.Interact(usr) feedback_add_details("admin_verb","EMP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return - + /datum/event/proc/findEventArea() //Here's a nice proc to use to find an area for your event to land in! var/area/candidate = null @@ -342,7 +343,7 @@ break return candidate - + /datum/event/proc/num_players() var/players = 0 for(var/mob/living/carbon/human/P in player_list) diff --git a/code/modules/events/grid_check.dm b/code/modules/events/grid_check.dm index 71d78d96e4a..c485827efbc 100644 --- a/code/modules/events/grid_check.dm +++ b/code/modules/events/grid_check.dm @@ -8,9 +8,7 @@ power_failure(0) /datum/event/grid_check/announce() - command_alert("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Automated Grid Check") - for(var/mob/M in player_list) - M << sound('sound/AI/poweroff.ogg') + command_announcement.Announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Automated Grid Check", new_sound = 'sound/AI/poweroff.ogg') /datum/event/grid_check/end() power_restore() diff --git a/code/modules/events/infestation.dm b/code/modules/events/infestation.dm index 8971db74853..444da4675ef 100644 --- a/code/modules/events/infestation.dm +++ b/code/modules/events/infestation.dm @@ -102,7 +102,7 @@ /datum/event/infestation/announce() - command_alert("Bioscans indicate that [vermstring] have been breeding in [locstring]. Clear them out, before this starts to affect productivity.", "Lifesign Alert") + command_announcement.Announce("Bioscans indicate that [vermstring] have been breeding in [locstring]. Clear them out, before this starts to affect productivity.", "Lifesign Alert") #undef LOC_KITCHEN #undef LOC_ATMOS diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm index 7f66a4366a9..9e8f5d43b57 100644 --- a/code/modules/events/ion_storm.dm +++ b/code/modules/events/ion_storm.dm @@ -6,7 +6,7 @@ /datum/event/ionstorm/announce() endWhen = rand(500, 1500) -// command_alert("The station has entered an ion storm. Monitor all electronic equipment for malfunctions", "Anomaly Alert") +// command_announcement.Announce("The station has entered an ion storm. Monitor all electronic equipment for malfunctions", "Anomaly Alert") for (var/mob/living/carbon/human/player in world) if(player.client) players += player.real_name @@ -86,7 +86,7 @@ /datum/event/ionstorm/end() spawn(rand(5000,8000)) if(prob(50)) - command_alert("It has come to our attention that the station passed through an ion storm. Please monitor all electronic equipment for malfunctions.", "Anomaly Alert") + command_announcement.Announce("It has come to our attention that the station passed through an ion storm. Please monitor all electronic equipment for malfunctions.", "Anomaly Alert") /* /proc/IonStorm(botEmagChance = 10) @@ -212,21 +212,21 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is spawn(0) world << "Started processing APCs" for (var/obj/machinery/power/apc/APC in world) - if(APC.z == 1) + if((APC.z in config.station_levels)) APC.ion_act() apcnum++ world << "Finished processing APCs. Processed: [apcnum]" spawn(0) world << "Started processing SMES" for (var/obj/machinery/power/smes/SMES in world) - if(SMES.z == 1) + if((SMES.z in config.station_levels)) SMES.ion_act() smesnum++ world << "Finished processing SMES. Processed: [smesnum]" spawn(0) world << "Started processing AIRLOCKS" for (var/obj/machinery/door/airlock/D in world) - if(D.z == 1) + if((D.z in config.station_levels)) //if(length(D.req_access) > 0 && !(12 in D.req_access)) //not counting general access and maintenance airlocks airlocknum++ spawn(0) @@ -235,7 +235,7 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is spawn(0) world << "Started processing FIREDOORS" for (var/obj/machinery/door/firedoor/D in world) - if(D.z == 1) + if((D.z in config.station_levels)) firedoornum++; spawn(0) D.ion_act() diff --git a/code/modules/events/mass_hallucination.dm b/code/modules/events/mass_hallucination.dm index 571a9ae7d1f..b3fbea5343c 100644 --- a/code/modules/events/mass_hallucination.dm +++ b/code/modules/events/mass_hallucination.dm @@ -3,4 +3,4 @@ if(!(C.species.flags & IS_SYNTHETIC)) C.hallucination += rand(50, 100) /datum/event/mass_hallucination/announce() - command_alert("It seems that station [station_name()] is passing through a minor radiation field, this may cause some hallucination, but no further damage") \ No newline at end of file + command_announcement.Announce("It seems that station [station_name()] is passing through a minor radiation field, this may cause some hallucination, but no further damage") \ No newline at end of file diff --git a/code/modules/events/meteors.dm b/code/modules/events/meteors.dm index 0f74d65b7d9..42b0b1eda1d 100644 --- a/code/modules/events/meteors.dm +++ b/code/modules/events/meteors.dm @@ -9,15 +9,14 @@ endWhen = rand(10,25) * 3 /datum/event/meteor_wave/announce() - command_alert("Meteors have been detected on collision course with the station.", "Meteor Alert") - world << sound('sound/AI/meteors.ogg') - + command_announcement.Announce("Meteors have been detected on collision course with the station.", "Meteor Alert", new_sound = 'sound/AI/meteors.ogg') + /datum/event/meteor_wave/tick() if(IsMultiple(activeFor, 3)) spawn_meteors(rand(2,5)) /datum/event/meteor_wave/end() - command_alert("The station has cleared the meteor storm.", "Meteor Alert") + command_announcement.Announce("The station has cleared the meteor storm.", "Meteor Alert") // /datum/event/meteor_shower @@ -30,7 +29,7 @@ waves = rand(1,4) /datum/event/meteor_shower/announce() - command_alert("The station is now in a meteor shower.", "Meteor Alert") + command_announcement.Announce("The station is now in a meteor shower.", "Meteor Alert") //meteor showers are lighter and more common, /datum/event/meteor_shower/tick() @@ -44,4 +43,4 @@ endWhen = next_meteor + 1 /datum/event/meteor_shower/end() - command_alert("The station has cleared the meteor shower", "Meteor Alert") + command_announcement.Announce("The station has cleared the meteor shower", "Meteor Alert") diff --git a/code/modules/events/prison_break.dm b/code/modules/events/prison_break.dm index 87135bda526..676661f2b7e 100644 --- a/code/modules/events/prison_break.dm +++ b/code/modules/events/prison_break.dm @@ -15,7 +15,7 @@ /datum/event/prison_break/announce() if(prisonAreas && prisonAreas.len > 0) - command_alert("[pick("Gr3y.T1d3 virus","Malignant trojan")] detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert") + command_announcement.Announce("[pick("Gr3y.T1d3 virus","Malignant trojan")] detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert") else world.log << "ERROR: Could not initate grey-tide. Unable find prison or brig area." kill() @@ -30,7 +30,7 @@ /datum/event/prison_break/announce() if(prisonAreas && prisonAreas.len > 0) - command_alert("[pick("Gr3y.T1d3 virus","Malignant trojan")] detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert") + command_announcement.Announce("[pick("Gr3y.T1d3 virus","Malignant trojan")] detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert") else world.log << "ERROR: Could not initate grey-tide. Unable find prison or brig area." kill() diff --git a/code/modules/events/radiation_storm.dm b/code/modules/events/radiation_storm.dm index 58b5f60c2cc..5daabc84799 100644 --- a/code/modules/events/radiation_storm.dm +++ b/code/modules/events/radiation_storm.dm @@ -22,11 +22,10 @@ /datum/event/radiation_storm/start() spawn() - world << sound('sound/AI/radiation.ogg') - command_alert("High levels of radiation detected near the station. Please evacuate into one of the shielded maintenance tunnels.", "Anomaly Alert") + command_announcement.Announce("High levels of radiation detected near the station. Please evacuate into one of the shielded maintenance tunnels.", "Anomaly Alert", new_sound = 'sound/AI/radiation.ogg') for(var/area/A in world) - if(A.z != 1 || is_safe_zone(A)) + if(!(A.z in config.station_levels) || is_safe_zone(A)) continue A.radiation_alert() @@ -36,7 +35,7 @@ sleep(600) - command_alert("The station has entered the radiation belt. Please remain in a sheltered area until we have passed the radiation belt.", "Anomaly Alert") + command_announcement.Announce("The station has entered the radiation belt. Please remain in a sheltered area until we have passed the radiation belt.", "Anomaly Alert") for(var/i = 0, i < 10, i++) for(var/mob/living/carbon/human/H in living_mob_list) @@ -45,7 +44,7 @@ var/turf/T = get_turf(H) if(!T) continue - if(T.z != 1 || is_safe_zone(T.loc)) + if(!(T.z in config.station_levels) || is_safe_zone(T.loc)) continue if(istype(H,/mob/living/carbon/human)) @@ -64,16 +63,16 @@ var/turf/T = get_turf(M) if(!T) continue - if(T.z != 1) + if(!(T.z in config.station_levels)) continue M.apply_effect((rand(5,25)),IRRADIATE,0) sleep(100) - command_alert("The station has passed the radiation belt. Please report to medbay if you experience any unusual symptoms. Maintenance will lose all access again shortly.", "Anomaly Alert") + command_announcement.Announce("The station has passed the radiation belt. Please report to medbay if you experience any unusual symptoms. Maintenance will lose all access again shortly.", "Anomaly Alert") for(var/area/A in world) - if(A.z != 1 || is_safe_zone(A)) + if(!(A.z in config.station_levels) || is_safe_zone(A)) continue A.reset_radiation_alert() diff --git a/code/modules/events/rogue_drones.dm b/code/modules/events/rogue_drones.dm index d3ccaa4d89a..d96c80f60f8 100644 --- a/code/modules/events/rogue_drones.dm +++ b/code/modules/events/rogue_drones.dm @@ -30,7 +30,7 @@ msg = "Contact has been lost with a combat drone wing operating out of the NMV Icarus. If any are sighted in the area, approach with caution." else msg = "Unidentified hackers have targetted a combat drone wing deployed from the NMV Icarus. If any are sighted in the area, approach with caution." - command_alert(msg, "Rogue drone alert") + command_announcement.Announce(msg, "Rogue drone alert") /datum/event/rogue_drone/tick() @@ -49,6 +49,6 @@ num_recovered++ if(num_recovered > drones_list.len * 0.75) - command_alert("Icarus drone control reports the malfunctioning wing has been recovered safely.", "Rogue drone alert") + command_announcement.Announce("Icarus drone control reports the malfunctioning wing has been recovered safely.", "Rogue drone alert") else - command_alert("Icarus drone control registers disappointment at the loss of the drones, but the survivors have been recovered.", "Rogue drone alert") + command_announcement.Announce("Icarus drone control registers disappointment at the loss of the drones, but the survivors have been recovered.", "Rogue drone alert") diff --git a/code/modules/events/sayuevents/meaty_ores.dm b/code/modules/events/sayuevents/meaty_ores.dm index a44708693ef..d6e640934d9 100644 --- a/code/modules/events/sayuevents/meaty_ores.dm +++ b/code/modules/events/sayuevents/meaty_ores.dm @@ -1,9 +1,8 @@ /datum/event/dust/meaty/announce() if(prob(16)) - command_alert("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert") + command_announcement.Announce("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert") else - command_alert("Meaty ores have been detected on collision course with the station.", "Meaty Ore Alert") - world << sound('sound/AI/meteors.ogg') + command_announcement.Announce("Meaty ores have been detected on collision course with the station.", "Meaty Ore Alert",new_sound = 'sound/AI/meteors.ogg') /datum/event/dust/meaty/setup() qnty = rand(45,125) diff --git a/code/modules/events/sayuevents/undead.dm b/code/modules/events/sayuevents/undead.dm index f9d82baf086..84c1c0bb1b1 100644 --- a/code/modules/events/sayuevents/undead.dm +++ b/code/modules/events/sayuevents/undead.dm @@ -8,7 +8,7 @@ RS.start() RS.kill() for(var/area/A) - if(A.z != 1) continue //Spook on main station only. + if(!(A.z in config.station_levels)) continue //Spook on main station only. if(A.luminosity) continue // if(A.lighting_space) continue if(A.type == /area) continue diff --git a/code/modules/events/sayuevents/wormholes.dm b/code/modules/events/sayuevents/wormholes.dm index e120d11630d..16daa8fe7c9 100644 --- a/code/modules/events/sayuevents/wormholes.dm +++ b/code/modules/events/sayuevents/wormholes.dm @@ -13,7 +13,7 @@ /datum/event/wormholes/start() for(var/turf/simulated/floor/T in world) - if(T.z == 1) + if((T.z in config.station_levels)) pick_turfs += T for(var/i = 1, i <= number_of_wormholes, i++) @@ -21,10 +21,7 @@ wormholes += new /obj/effect/portal/wormhole(T, null, null, -1) /datum/event/wormholes/announce() - command_alert("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert") - for(var/mob/M in player_list) - if(!istype(M, /mob/new_player)) - M << sound('sound/AI/spanomalies.ogg') + command_announcement.Announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert", new_sound = 'sound/AI/spanomalies.ogg') /datum/event/wormholes/tick() if(activeFor % shift_frequency == 0) @@ -49,7 +46,7 @@ /obj/effect/portal/wormhole/attack_hand(mob/user) teleport(user) -/obj/effect/portal/wormhole/attackby(obj/item/I, mob/user) +/obj/effect/portal/wormhole/attackby(obj/item/I, mob/user, params) teleport(user) /obj/effect/portal/wormhole/teleport(atom/movable/M) diff --git a/code/modules/events/spider_infestation.dm b/code/modules/events/spider_infestation.dm index 7a953d3fd40..227737ba99c 100644 --- a/code/modules/events/spider_infestation.dm +++ b/code/modules/events/spider_infestation.dm @@ -12,15 +12,13 @@ sent_spiders_to_station = 1 /datum/event/spider_infestation/announce() - command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert") - world << sound('sound/AI/aliens.ogg') - + command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg') /datum/event/spider_infestation/start() var/list/vents = list() for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world) - if(temp_vent.loc.z == 1 && !temp_vent.welded && temp_vent.network) + if((temp_vent.loc.z in config.station_levels) && !temp_vent.welded && temp_vent.network) if(temp_vent.network.normal_members.len > 50) vents += temp_vent diff --git a/code/modules/events/tear.dm b/code/modules/events/tear.dm index d5d572c3b6a..a11455b351d 100644 --- a/code/modules/events/tear.dm +++ b/code/modules/events/tear.dm @@ -5,7 +5,7 @@ var/obj/effect/tear/TE /datum/event/tear/announce() - command_alert("A tear in the fabric of space and time has opened. Expected location: [impact_area.name].", "Anomaly Alert") + command_announcement.Announce("A tear in the fabric of space and time has opened. Expected location: [impact_area.name].", "Anomaly Alert") /datum/event/tear/start() diff --git a/code/modules/events/tgevents/alien_infestation.dm b/code/modules/events/tgevents/alien_infestation.dm deleted file mode 100644 index 3d1dca58bc2..00000000000 --- a/code/modules/events/tgevents/alien_infestation.dm +++ /dev/null @@ -1,40 +0,0 @@ -/var/global/sent_aliens_to_station = 0 - -/datum/event/alien_infestation - announceWhen = 400 - - var/spawncount = 1 - var/successSpawn = 0 //So we don't make a command report if nothing gets spawned. - - -/datum/event/alien_infestation/setup() - announceWhen = rand(announceWhen, announceWhen + 50) - spawncount = rand(1, 2) - sent_aliens_to_station = 1 - - -/datum/event/alien_infestation/announce() - if(successSpawn) - command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert") - world << sound('sound/AI/aliens.ogg') - - -/datum/event/alien_infestation/start() - var/list/vents = list() - for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world) - if(temp_vent.loc.z == 1 && !temp_vent.welded && temp_vent.network) - if(temp_vent.network.normal_members.len > 50) //Stops Aliens getting stuck in small networks. See: Security, Virology - vents += temp_vent - - var/list/candidates = get_candidates(BE_ALIEN,ALIEN_AFK_BRACKET,"alien","Syndicate") - - while(spawncount > 0 && vents.len && candidates.len) - var/obj/vent = pick_n_take(vents) - var/client/C = pick_n_take(candidates) - if(C) - respawnable_list -= C - var/mob/living/carbon/alien/larva/new_xeno = new(vent.loc) - new_xeno.key = C.key - - spawncount-- - successSpawn = 1 \ No newline at end of file diff --git a/code/modules/events/tgevents/anomaly.dm b/code/modules/events/tgevents/anomaly.dm index 7ab1f25c9ca..a1f951f5747 100644 --- a/code/modules/events/tgevents/anomaly.dm +++ b/code/modules/events/tgevents/anomaly.dm @@ -15,7 +15,7 @@ setup(safety_loop) /datum/event/anomaly/announce() - command_alert("Localized hyper-energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert") + command_announcement.Announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert") /datum/event/anomaly/start() var/turf/T = pick(get_area_turfs(impact_area)) diff --git a/code/modules/events/tgevents/anomaly_bluespace.dm b/code/modules/events/tgevents/anomaly_bluespace.dm index 224f6f0e2de..852680e69fa 100644 --- a/code/modules/events/tgevents/anomaly_bluespace.dm +++ b/code/modules/events/tgevents/anomaly_bluespace.dm @@ -4,7 +4,7 @@ endWhen = 160 /datum/event/anomaly/anomaly_bluespace/announce() - command_alert("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") + command_announcement.Announce("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") /datum/event/anomaly/anomaly_bluespace/start() @@ -21,7 +21,7 @@ var/obj/item/device/radio/beacon/chosen var/list/possible = list() for(var/obj/item/device/radio/beacon/W in world) - if(W.z != 1) + if(!(W.z in config.station_levels)) continue possible += W @@ -35,7 +35,7 @@ var/turf/TO = get_turf(chosen) // the turf of origin we're travelling TO playsound(TO, 'sound/effects/phasein.ogg', 100, 1) - command_alert("Massive bluespace translocation detected.", "Anomaly Alert") + command_announcement.Announce("Massive bluespace translocation detected.", "Anomaly Alert") var/list/flashers = list() for(var/mob/living/carbon/human/M in viewers(TO, null)) diff --git a/code/modules/events/tgevents/anomaly_flux.dm b/code/modules/events/tgevents/anomaly_flux.dm index bf2cb2d18cc..d02af07b3ef 100644 --- a/code/modules/events/tgevents/anomaly_flux.dm +++ b/code/modules/events/tgevents/anomaly_flux.dm @@ -4,7 +4,7 @@ endWhen = 180 /datum/event/anomaly/anomaly_flux/announce() - command_alert("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") + command_announcement.Announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") /datum/event/anomaly/anomaly_flux/start() var/turf/T = pick(get_area_turfs(impact_area)) diff --git a/code/modules/events/tgevents/anomaly_grav.dm b/code/modules/events/tgevents/anomaly_grav.dm index c5430625ea8..0c9f3776f82 100644 --- a/code/modules/events/tgevents/anomaly_grav.dm +++ b/code/modules/events/tgevents/anomaly_grav.dm @@ -4,7 +4,7 @@ endWhen = 70 /datum/event/anomaly/anomaly_grav/announce() - command_alert("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") + command_announcement.Announce("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") /datum/event/anomaly/anomaly_grav/start() var/turf/T = pick(get_area_turfs(impact_area)) diff --git a/code/modules/events/tgevents/anomaly_pyro.dm b/code/modules/events/tgevents/anomaly_pyro.dm index 4e7f6a0b947..df4805121cd 100644 --- a/code/modules/events/tgevents/anomaly_pyro.dm +++ b/code/modules/events/tgevents/anomaly_pyro.dm @@ -4,7 +4,7 @@ endWhen = 110 /datum/event/anomaly/anomaly_pyro/announce() - command_alert("Atmospheric anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") + command_announcement.Announce("Atmospheric anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") /datum/event/anomaly/anomaly_pyro/start() var/turf/T = pick(get_area_turfs(impact_area)) diff --git a/code/modules/events/tgevents/anomaly_vortex.dm b/code/modules/events/tgevents/anomaly_vortex.dm index 6f2f999e728..c950444978e 100644 --- a/code/modules/events/tgevents/anomaly_vortex.dm +++ b/code/modules/events/tgevents/anomaly_vortex.dm @@ -4,7 +4,7 @@ endWhen = 80 /datum/event/anomaly/anomaly_vortex/announce() - command_alert("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name]", "Anomaly Alert") + command_announcement.Announce("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name]", "Anomaly Alert") /datum/event/anomaly/anomaly_vortex/start() var/turf/T = pick(get_area_turfs(impact_area)) diff --git a/code/modules/events/tgevents/brand_intelligence.dm b/code/modules/events/tgevents/brand_intelligence.dm index 893cee98cf1..1cfeba0cd08 100644 --- a/code/modules/events/tgevents/brand_intelligence.dm +++ b/code/modules/events/tgevents/brand_intelligence.dm @@ -8,7 +8,7 @@ /datum/event/brand_intelligence/announce() - command_alert("Rampant brand intelligence has been detected aboard [station_name()], please stand-by.", "Machine Learning Alert") + command_announcement.Announce("Rampant brand intelligence has been detected aboard [station_name()], please stand-by.", "Machine Learning Alert") /datum/event/brand_intelligence/start() diff --git a/code/modules/events/tgevents/immovable_rod.dm b/code/modules/events/tgevents/immovable_rod.dm index 25c3d0308d4..ec86e89981f 100644 --- a/code/modules/events/tgevents/immovable_rod.dm +++ b/code/modules/events/tgevents/immovable_rod.dm @@ -12,7 +12,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 announceWhen = 5 /datum/event/immovable_rod/announce() - command_alert("What the fuck was that?!", "General Alert") + command_announcement.Announce("What the fuck was that?!", "General Alert") /datum/event/immovable_rod/start() var/startx = 0 diff --git a/code/modules/events/tgevents/mass_hallucination.dm b/code/modules/events/tgevents/mass_hallucination.dm index 6a34331acb3..f23a2c15510 100644 --- a/code/modules/events/tgevents/mass_hallucination.dm +++ b/code/modules/events/tgevents/mass_hallucination.dm @@ -6,4 +6,4 @@ if(!(C.species.flags & IS_SYNTHETIC)) C.hallucination += rand(50, 100) /datum/event/mass_hallucination/announce() - command_alert("It seems that station [station_name()] is passing through a minor radiation field, this may cause some hallucination, but no further damage") \ No newline at end of file + command_announcement.Announce("It seems that station [station_name()] is passing through a minor radiation field, this may cause some hallucination, but no further damage") \ No newline at end of file diff --git a/code/modules/events/tgevents/spider_infestation.dm b/code/modules/events/tgevents/spider_infestation.dm deleted file mode 100644 index 1f4cccdf418..00000000000 --- a/code/modules/events/tgevents/spider_infestation.dm +++ /dev/null @@ -1,33 +0,0 @@ -/var/global/sent_spiders_to_station = 0 - -/datum/event/spider_infestation - announceWhen = 400 - - var/spawncount = 1 - - -/datum/event/spider_infestation/setup() - announceWhen = rand(announceWhen, announceWhen + 50) - spawncount = round(num_players() * 1.5) - sent_spiders_to_station = 1 - -/datum/event/spider_infestation/announce() - command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert") - world << sound('sound/AI/aliens.ogg') - - -/datum/event/spider_infestation/start() - - var/list/vents = list() - for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world) - if(temp_vent.loc.z == 1 && !temp_vent.welded && temp_vent.network) - if(temp_vent.network.normal_members.len > 50) - vents += temp_vent - - while((spawncount >= 1) && vents.len) - var/obj/vent = pick(vents) - var/obj/effect/spider/spiderling/S = new(vent.loc) - if(prob(66)) - S.grow_as = /mob/living/simple_animal/hostile/giant_spider/nurse - vents -= vent - spawncount-- \ No newline at end of file diff --git a/code/modules/events/tgevents/vent_clog.dm b/code/modules/events/tgevents/vent_clog.dm index 885552dff28..061450a197d 100755 --- a/code/modules/events/tgevents/vent_clog.dm +++ b/code/modules/events/tgevents/vent_clog.dm @@ -6,13 +6,13 @@ var/list/vents = list() /datum/event/vent_clog/announce() - command_alert("The scrubbers network is experiencing a backpressure surge. Some ejection of contents may occur.", "Atmospherics alert") + command_announcement.Announce("The scrubbers network is experiencing a backpressure surge. Some ejection of contents may occur.", "Atmospherics alert") /datum/event/vent_clog/setup() endWhen = rand(25, 100) for(var/obj/machinery/atmospherics/unary/vent_scrubber/temp_vent in machines) - if(temp_vent.loc.z == 1 && temp_vent.network) + if((temp_vent.loc.z in config.station_levels) && temp_vent.network) if(temp_vent.network.normal_members.len > 50) vents += temp_vent diff --git a/code/modules/events/viral_infection.dm b/code/modules/events/viral_infection.dm index 876e3453896..9ee3a47077a 100644 --- a/code/modules/events/viral_infection.dm +++ b/code/modules/events/viral_infection.dm @@ -8,8 +8,7 @@ datum/event/viral_infection/setup() severity = rand(1, 3) datum/event/viral_infection/announce() - command_alert("Confirmed outbreak of level five viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert") - world << sound('sound/AI/outbreak5.ogg') + command_announcement.Announce("Confirmed outbreak of level five viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak5.ogg') datum/event/viral_infection/start() var/list/candidates = list() //list of candidate keys diff --git a/code/modules/events/viral_outbreak.dm b/code/modules/events/viral_outbreak.dm index f11acd511f3..9e139f5742b 100644 --- a/code/modules/events/viral_outbreak.dm +++ b/code/modules/events/viral_outbreak.dm @@ -8,8 +8,7 @@ datum/event/viral_outbreak/setup() severity = rand(2, 4) datum/event/viral_outbreak/announce() - command_alert("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert") - world << sound('sound/AI/outbreak7.ogg') + command_announcement.Announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg') datum/event/viral_outbreak/start() var/list/candidates = list() //list of candidate keys diff --git a/code/modules/events/wallrot.dm b/code/modules/events/wallrot.dm index dfaedf451ec..b36f7f93760 100644 --- a/code/modules/events/wallrot.dm +++ b/code/modules/events/wallrot.dm @@ -1,20 +1,13 @@ -/turf/simulated/wall - - -datum/event/wallrot - severity = 1 - datum/event/wallrot/setup() announceWhen = rand(0, 300) endWhen = announceWhen + 1 - severity = rand(5, 10) datum/event/wallrot/announce() - command_alert("Harmful fungi detected on station. Station structures may be contaminated.", "Biohazard Alert") + command_announcement.Announce("Harmful fungi detected on station. Station structures may be contaminated.", "Biohazard Alert") datum/event/wallrot/start() spawn() - var/turf/center = null + var/turf/simulated/wall/center = null // 100 attempts for(var/i=0, i<100, i++) @@ -24,14 +17,15 @@ datum/event/wallrot/start() if(center) // Make sure at least one piece of wall rots! - center:rot() + center.rot() // Have a chance to rot lots of other walls. var/rotcount = 0 + var/actual_severity = severity * rand(5, 10) for(var/turf/simulated/wall/W in range(5, center)) if(prob(50)) - W:rot() + W.rot() rotcount++ // Only rot up to severity walls - if(rotcount >= severity) + if(rotcount >= actual_severity) break \ No newline at end of file diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index bc39a2cbf00..19405dfaf06 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -11,18 +11,19 @@ Gunshots/explosions/opening doors/less rare audio (done) */ -mob/living/carbon/var - image/halimage - image/halbody - obj/halitem - hal_screwyhud = 0 //1 - critical, 2 - dead, 3 - oxygen indicator, 4 - toxin indicator - handling_hal = 0 - hal_crit = 0 +mob/living/carbon/ + var/image/halimage + var/image/halbody + var/obj/halitem + var/hal_screwyhud = 0 //1 - critical, 2 - dead, 3 - oxygen indicator, 4 - toxin indicator + var/handling_hal = 0 + var/hal_crit = 0 mob/living/carbon/proc/handle_hallucinations() - if(handling_hal) return + if(handling_hal) + return handling_hal = 1 - while(client && hallucination > 20) + while(hallucination > 20) sleep(rand(200,500)/(hallucination/25)) var/halpick = rand(1,100) switch(halpick) @@ -77,9 +78,7 @@ mob/living/carbon/proc/handle_hallucinations() halitem.name = "Flashbang" if(client) client.screen += halitem spawn(rand(100,250)) - if(client) - client.screen -= halitem - halitem = null + qdel(halitem) if(26 to 40) //Flashes of danger //src << "Danger Flash" @@ -111,7 +110,7 @@ mob/living/carbon/proc/handle_hallucinations() if(41 to 65) //Strange audio //src << "Strange Audio" - switch(rand(1,12)) + switch(rand(1,14)) if(1) src << 'sound/machines/airlock.ogg' if(2) if(prob(50))src << 'sound/effects/Explosion1.ogg' @@ -142,9 +141,14 @@ mob/living/carbon/proc/handle_hallucinations() 'sound/hallucinations/look_up1.ogg', 'sound/hallucinations/look_up2.ogg', 'sound/hallucinations/over_here1.ogg', 'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg',\ 'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/turn_around2.ogg', 'sound/hallucinations/veryfar_noise.ogg', 'sound/hallucinations/wail.ogg') src << pick(creepyasssounds) + if(13) + src << "You feel a tiny prick!" + if(14) + src << "

Priority Announcement

" + src << "

The Emergency Shuttle has docked with the station. You have 3 minutes to board the Emergency Shuttle.

" + src << sound('sound/AI/shuttledock.ogg') if(66 to 70) //Flashes of danger - //src << "Danger Flash" if(!halbody) var/list/possible_points = list() for(var/turf/simulated/floor/F in view(src,world.view)) @@ -158,8 +162,6 @@ mob/living/carbon/proc/handle_hallucinations() halbody = image('icons/mob/human.dmi',target,"husk_s",TURF_LAYER) if(4) halbody = image('icons/mob/alien.dmi',target,"alienother",TURF_LAYER) - // if(5) - // halbody = image('xcomalien.dmi',target,"chryssalid",TURF_LAYER) if(client) client.images += halbody spawn(rand(50,80)) //Only seen for a brief moment. @@ -167,55 +169,58 @@ mob/living/carbon/proc/handle_hallucinations() halbody = null if(71 to 72) //Fake death -// src.sleeping_willingly = 1 src.sleeping = 20 hal_crit = 1 hal_screwyhud = 1 spawn(rand(50,100)) -// src.sleeping_willingly = 0 src.sleeping = 0 hal_crit = 0 hal_screwyhud = 0 + if(73 to 75) + fake_attack() handling_hal = 0 +/mob/living/carbon/proc/fake_attack() +// var/list/possible_clones = new/list() + var/mob/living/carbon/human/clone = null + var/clone_weapon = null + for(var/mob/living/carbon/human/H in living_mob_list) + if(H.stat || H.lying) + continue +// possible_clones += H + clone = H + break //changed the code a bit. Less randomised, but less work to do. Should be ok, world.contents aren't stored in any particular order. -/*obj/machinery/proc/mockpanel(list/buttons,start_txt,end_txt,list/mid_txts) +// if(!possible_clones.len) return +// clone = pick(possible_clones) + if(!clone) + return - if(!mocktxt) + //var/obj/effect/fake_attacker/F = new/obj/effect/fake_attacker(outside_range(target)) + var/obj/effect/fake_attacker/F = new/obj/effect/fake_attacker(src.loc) + if(clone.l_hand) + if(!(locate(clone.l_hand) in non_fakeattack_weapons)) + clone_weapon = clone.l_hand.name + F.weap = clone.l_hand + else if (clone.r_hand) + if(!(locate(clone.r_hand) in non_fakeattack_weapons)) + clone_weapon = clone.r_hand.name + F.weap = clone.r_hand - mocktxt = "" + F.name = clone.name + F.my_target = src + F.weapon_name = clone_weapon + src.hallucinations += F - var/possible_txt = list("Launch Escape Pods","Self-Destruct Sequence","\[Swipe ID\]","De-Monkify",\ - "Reticulate Splines","Plasma","Open Valve","Lockdown","Nerf Airflow","Kill Traitor","Nihilism",\ - "OBJECTION!","Arrest Stephen Bowman","Engage Anti-Trenna Defenses","Increase Captain IQ","Retrieve Arms",\ - "Play Charades","Oxygen","Inject BeAcOs","Ninja Lizards","Limit Break","Build Sentry") + F.left = image(clone,dir = WEST) + F.right = image(clone,dir = EAST) + F.up = image(clone,dir = NORTH) + F.down = image(clone,dir = SOUTH) - if(mid_txts) - while(mid_txts.len) - var/mid_txt = pick(mid_txts) - mocktxt += mid_txt - mid_txts -= mid_txt + F.updateimage() - while(buttons.len) - - var/button = pick(buttons) - - var/button_txt = pick(possible_txt) - - mocktxt += "[button_txt]
" - - buttons -= button - possible_txt -= button_txt - - return start_txt + mocktxt + end_txt + "
" - -proc/check_panel(mob/M) - if (istype(M, /mob/living/carbon/human) || istype(M, /mob/living/silicon/ai)) - if(M.hallucination < 15) - return 1 - return 0*/ /obj/effect/fake_attacker icon = null @@ -231,7 +236,7 @@ proc/check_panel(mob/M) var/image/stand_icon = null var/image/currentimage = null var/icon/base = null - var/s_tone + var/skin_tone var/mob/living/clone = null var/image/left var/image/right @@ -241,99 +246,103 @@ proc/check_panel(mob/M) var/health = 100 - attackby(var/obj/item/weapon/P as obj, mob/user as mob) +/obj/effect/fake_attacker/attackby(var/obj/item/weapon/P as obj, mob/living/user as mob, params) + step_away(src,my_target,2) + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) + my_target << sound(pick('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg')) + my_target.visible_message("[my_target] flails around wildly.", \ + "[my_target] has attacked [src]!") + + src.health -= P.force + + + return + +/obj/effect/fake_attacker/Crossed(var/mob/M, somenumber) + if(M == my_target) step_away(src,my_target,2) - for(var/mob/M in oviewers(world.view,my_target)) - M << "\red [my_target] flails around wildly." - my_target.show_message("\red [src] has been attacked by [my_target] ", 1) //Lazy. + if(prob(30)) + for(var/mob/O in oviewers(world.view , my_target)) + O << "[my_target] stumbles around." - src.health -= P.force +/obj/effect/fake_attacker/New() + ..() + spawn(300) + if(my_target) + my_target.hallucinations -= src + qdel(src) + step_away(src,my_target,2) + spawn attack_loop() - return - - Crossed(var/mob/M, somenumber) - if(M == my_target) - step_away(src,my_target,2) - if(prob(30)) - for(var/mob/O in oviewers(world.view , my_target)) - O << "\red [my_target] stumbles around." - - New() - ..() - spawn(300) - if(my_target) - my_target.hallucinations -= src - del(src) - step_away(src,my_target,2) - spawn attack_loop() +/obj/effect/fake_attacker/proc/updateimage() +// del src.currentimage - proc/updateimage() - // del src.currentimage + if(src.dir == NORTH) + del src.currentimage + src.currentimage = new /image(up,src) + else if(src.dir == SOUTH) + del src.currentimage + src.currentimage = new /image(down,src) + else if(src.dir == EAST) + del src.currentimage + src.currentimage = new /image(right,src) + else if(src.dir == WEST) + del src.currentimage + src.currentimage = new /image(left,src) + my_target << currentimage - if(src.dir == NORTH) - del src.currentimage - src.currentimage = new /image(up,src) - else if(src.dir == SOUTH) - del src.currentimage - src.currentimage = new /image(down,src) - else if(src.dir == EAST) - del src.currentimage - src.currentimage = new /image(right,src) - else if(src.dir == WEST) - del src.currentimage - src.currentimage = new /image(left,src) - my_target << currentimage - - - proc/attack_loop() - while(1) - sleep(rand(5,10)) - if(src.health < 0) - collapse() - continue - if(get_dist(src,my_target) > 1) - src.dir = get_dir(src,my_target) - step_towards(src,my_target) - updateimage() - else - if(prob(15)) - if(weapon_name) - my_target << sound(pick('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg')) - my_target.show_message("\red [my_target] has been attacked with [weapon_name] by [src.name] ", 1) - my_target.staminaloss += 30 - if(prob(20)) my_target.eye_blurry += 3 - if(prob(33)) - if(!locate(/obj/effect/overlay) in my_target.loc) - fake_blood(my_target) - else - my_target << sound(pick('sound/weapons/punch1.ogg','sound/weapons/punch2.ogg','sound/weapons/punch3.ogg','sound/weapons/punch4.ogg')) - my_target.show_message("\red [src.name] has punched [my_target]!", 1) - my_target.staminaloss += 30 - if(prob(33)) - if(!locate(/obj/effect/overlay) in my_target.loc) - fake_blood(my_target) - +/obj/effect/fake_attacker/proc/attack_loop() + while(1) + sleep(rand(5,10)) + if(src.health < 0) + collapse() + continue + if(get_dist(src,my_target) > 1) + src.dir = get_dir(src,my_target) + step_towards(src,my_target) + updateimage() + else if(prob(15)) - step_away(src,my_target,2) + src.do_attack_animation(my_target) + if(weapon_name) + my_target << sound(pick('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg')) + my_target.show_message("[src.name] has attacked [my_target] with [weapon_name]!", 1) + my_target.staminaloss += 30 + if(prob(20)) + my_target.eye_blurry += 3 + if(prob(33)) + if(!locate(/obj/effect/overlay) in my_target.loc) + fake_blood(my_target) + else + my_target << sound(pick('sound/weapons/punch1.ogg','sound/weapons/punch2.ogg','sound/weapons/punch3.ogg','sound/weapons/punch4.ogg')) + my_target.show_message("[src.name] has punched [my_target]!", 1) + my_target.staminaloss += 30 + if(prob(33)) + if(!locate(/obj/effect/overlay) in my_target.loc) + fake_blood(my_target) - proc/collapse() - collapse = 1 - updateimage() + if(prob(15)) + step_away(src,my_target,2) -/proc/fake_blood(var/mob/target) +/obj/effect/fake_attacker/proc/collapse() + collapse = 1 + updateimage() + +/obj/effect/fake_attacker/proc/fake_blood(var/mob/target) var/obj/effect/overlay/O = new/obj/effect/overlay(target.loc) O.name = "blood" var/image/I = image('icons/effects/blood.dmi',O,"floor[rand(1,7)]",O.dir,1) target << I spawn(300) - del(O) + qdel(O) return var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/item/ammo_box/a357,\ - /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow, /obj/item/weapon/melee/energy/sword,\ + /obj/item/weapon/gun/energy/crossbow, /obj/item/weapon/melee/energy/sword,\ /obj/item/weapon/storage/box/syndicate, /obj/item/weapon/storage/box/emps,\ /obj/item/weapon/cartridge/syndicate, /obj/item/clothing/under/chameleon,\ /obj/item/clothing/shoes/syndigaloshes, /obj/item/weapon/card/id/syndicate,\ @@ -347,65 +356,3 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite /obj/item/clothing/under/rank/captain, /obj/item/device/aicard,\ /obj/item/clothing/shoes/magboots, /obj/item/blueprints, /obj/item/weapon/disk/nuclear,\ /obj/item/clothing/suit/space/nasavoid, /obj/item/weapon/tank) - -/proc/fake_attack(var/mob/living/target) -// var/list/possible_clones = new/list() - var/mob/living/carbon/human/clone = null - var/clone_weapon = null - - for(var/mob/living/carbon/human/H in living_mob_list) - if(H.stat || H.lying) continue -// possible_clones += H - clone = H - break //changed the code a bit. Less randomised, but less work to do. Should be ok, world.contents aren't stored in any particular order. - -// if(!possible_clones.len) return -// clone = pick(possible_clones) - if(!clone) return - - //var/obj/effect/fake_attacker/F = new/obj/effect/fake_attacker(outside_range(target)) - var/obj/effect/fake_attacker/F = new/obj/effect/fake_attacker(target.loc) - if(clone.l_hand) - if(!(locate(clone.l_hand) in non_fakeattack_weapons)) - clone_weapon = clone.l_hand.name - F.weap = clone.l_hand - else if (clone.r_hand) - if(!(locate(clone.r_hand) in non_fakeattack_weapons)) - clone_weapon = clone.r_hand.name - F.weap = clone.r_hand - - F.name = clone.name - F.my_target = target - F.weapon_name = clone_weapon - target.hallucinations += F - - - F.left = image(clone,dir = WEST) - F.right = image(clone,dir = EAST) - F.up = image(clone,dir = NORTH) - F.down = image(clone,dir = SOUTH) - -// F.base = new /icon(clone.stand_icon) -// F.currentimage = new /image(clone) - -/* - - - - F.left = new /icon(clone.stand_icon,dir=WEST) - for(var/icon/i in clone.overlays) - F.left.Blend(i) - F.up = new /icon(clone.stand_icon,dir=NORTH) - for(var/icon/i in clone.overlays) - F.up.Blend(i) - F.down = new /icon(clone.stand_icon,dir=SOUTH) - for(var/icon/i in clone.overlays) - F.down.Blend(i) - F.right = new /icon(clone.stand_icon,dir=EAST) - for(var/icon/i in clone.overlays) - F.right.Blend(i) - - target << F.up - */ - - F.updateimage() diff --git a/code/modules/food/cooker.dm b/code/modules/food/cooker.dm index 9dbe39fa93d..798d0d80f07 100644 --- a/code/modules/food/cooker.dm +++ b/code/modules/food/cooker.dm @@ -90,7 +90,7 @@ obj/machinery/cooker/proc/gettype() var/obj/item/weapon/reagent_containers/food/snacks/type = new(get_turf(src)) return type -obj/machinery/cooker/attackby(obj/item/I, mob/user) +obj/machinery/cooker/attackby(obj/item/I, mob/user, params) if(stat & (NOPOWER|BROKEN)) return if (!checkValid(I, user)) diff --git a/code/modules/food/customizables.dm b/code/modules/food/customizables.dm index 29f5ad2eed8..62148b5e613 100644 --- a/code/modules/food/customizables.dm +++ b/code/modules/food/customizables.dm @@ -1,31 +1,31 @@ -/obj/item/weapon/reagent_containers/food/snacks/breadslice/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/weapon/reagent_containers/food/snacks/breadslice/attackby(obj/item/W as obj, mob/user as mob, params) var/obj/item/weapon/reagent_containers/food/snacks/customizable/sandwich/S = new(get_turf(user)) - S.attackby(W,user) + S.attackby(W,user, params) qdel(src) -/obj/item/weapon/reagent_containers/food/snacks/bun/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/weapon/reagent_containers/food/snacks/bun/attackby(obj/item/W as obj, mob/user as mob, params) var/obj/item/weapon/reagent_containers/food/snacks/customizable/burger/S = new(get_turf(user)) - S.attackby(W,user) + S.attackby(W,user, params) qdel(src) -/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough/attackby(obj/item/W as obj, mob/user as mob, params) if(!istype(W, /obj/item/weapon/kitchenknife)) //Ignore this if object is kitchen knife - make dough slices instead of kitchen knife pizza var/obj/item/weapon/reagent_containers/food/snacks/customizable/pizza/S = new(get_turf(user)) - S.attackby(W,user) + S.attackby(W,user, params) qdel(src) else //It's a kitchen knife. Go do the parent proc (slicing) ..() -/obj/item/weapon/reagent_containers/food/snacks/boiledspagetti/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/weapon/reagent_containers/food/snacks/boiledspagetti/attackby(obj/item/W as obj, mob/user as mob, params) var/obj/item/weapon/reagent_containers/food/snacks/customizable/pasta/S = new(get_turf(user)) - S.attackby(W,user) + S.attackby(W,user, params) qdel(src) -/obj/item/trash/plate/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/trash/plate/attackby(obj/item/W as obj, mob/user as mob, params) var/obj/item/weapon/reagent_containers/food/snacks/customizable/fullycustom/S = new(get_turf(user)) - S.attackby(W,user) + S.attackby(W,user, params) qdel(src) /obj/item/trash/bowl @@ -34,11 +34,11 @@ icon = 'icons/obj/food.dmi' icon_state = "soup" -/obj/item/trash/bowl/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/trash/bowl/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W,/obj/item/)) var/obj/item/weapon/reagent_containers/food/snacks/customizable/soup/S = new(get_turf(user)) - S.attackby(W,user) + S.attackby(W,user, params) qdel(src) ..() @@ -311,7 +311,7 @@ basename = "burger" toptype = new /obj/item/weapon/reagent_containers/food/snacks/bun() -/obj/item/weapon/reagent_containers/food/snacks/customizable/attackby(obj/item/I, mob/user) +/obj/item/weapon/reagent_containers/food/snacks/customizable/attackby(obj/item/I, mob/user, params) if(src.contents.len > sandwich_limit) user << "If you put anything else in or on [src] it's going to make a mess." return diff --git a/code/modules/food/icecream_vat.dm b/code/modules/food/icecream_vat.dm index 17a2e505720..19101f5b8e1 100644 --- a/code/modules/food/icecream_vat.dm +++ b/code/modules/food/icecream_vat.dm @@ -29,7 +29,7 @@ R.my_atom = src -/obj/machinery/icemachine/attackby(obj/item/I, mob/user) +/obj/machinery/icemachine/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/weapon/reagent_containers/glass)) if(beaker) user << "A container is already inside [src]." diff --git a/code/modules/food/oven.dm b/code/modules/food/oven.dm index f774c8ea7d0..fc081e8aa43 100644 --- a/code/modules/food/oven.dm +++ b/code/modules/food/oven.dm @@ -15,7 +15,7 @@ ..() updatefood() -/obj/machinery/cooking/attackby(obj/item/I, mob/user) +/obj/machinery/cooking/attackby(obj/item/I, mob/user, params) if(on) user << "The machine is already running." return @@ -41,7 +41,7 @@ else icon_state = "mixer_off" C.loc = get_turf(src) - C.attackby(F,user) + C.attackby(F,user, params) playsound(loc, 'sound/machines/ding.ogg', 50, 1) updatefood() return diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm index 60adf1e7046..ddde6434184 100644 --- a/code/modules/games/cards.dm +++ b/code/modules/games/cards.dm @@ -42,7 +42,7 @@ P.card_icon = "joker" cards += P -/obj/item/weapon/deck/attackby(obj/O as obj, mob/user as mob) +/obj/item/weapon/deck/attackby(obj/O as obj, mob/user as mob, params) if(istype(O,/obj/item/weapon/hand)) var/obj/item/weapon/hand/H = O for(var/datum/playingcard/P in H.cards) @@ -118,7 +118,7 @@ usr.visible_message("\The [usr] deals a card to \the [M].") H.throw_at(get_step(M,M.dir),10,1,H) -/obj/item/weapon/hand/attackby(obj/O as obj, mob/user as mob) +/obj/item/weapon/hand/attackby(obj/O as obj, mob/user as mob, params) if(istype(O,/obj/item/weapon/hand)) var/obj/item/weapon/hand/H = O for(var/datum/playingcard/P in H.cards) diff --git a/code/modules/hydroponics/grown_inedible.dm b/code/modules/hydroponics/grown_inedible.dm index 7db850670f1..ba5147785ae 100644 --- a/code/modules/hydroponics/grown_inedible.dm +++ b/code/modules/hydroponics/grown_inedible.dm @@ -43,7 +43,6 @@ icon = 'icons/obj/harvest.dmi' icon_state = "logs" force = 5 - flags = TABLEPASS throwforce = 5 w_class = 3.0 throw_speed = 3 @@ -51,7 +50,7 @@ origin_tech = "materials=1" attack_verb = list("bashed", "battered", "bludgeoned", "whacked") - attackby(obj/item/weapon/W as obj, mob/user as mob) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/circular_saw) || istype(W, /obj/item/weapon/hatchet) || (istype(W, /obj/item/weapon/twohanded/fireaxe) && W:wielded) || istype(W, /obj/item/weapon/melee/energy)) user.show_message("You make planks out of \the [src]!", 1) for(var/i=0,i<2,i++) @@ -61,7 +60,7 @@ continue if(G.amount>=G.max_amount) continue - G.attackby(NG, user) + G.attackby(NG, user, params) usr << "You add the newly-formed wood to the stack. It now contains [NG.amount] planks." del(src) return @@ -74,7 +73,6 @@ icon_state = "sunflower" damtype = "fire" force = 0 - flags = TABLEPASS throwforce = 1 w_class = 1.0 throw_speed = 1 @@ -92,7 +90,6 @@ icon_state = "nettle" damtype = "fire" force = 15 - flags = TABLEPASS throwforce = 1 w_class = 2.0 throw_speed = 1 @@ -135,7 +132,6 @@ icon_state = "deathnettle" damtype = "fire" force = 30 - flags = TABLEPASS throwforce = 1 w_class = 2.0 throw_speed = 1 @@ -205,7 +201,7 @@ throw_speed = 4 throw_range = 20 -/obj/item/weapon/corncob/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/corncob/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if(istype(W, /obj/item/weapon/circular_saw) || istype(W, /obj/item/weapon/hatchet) || istype(W, /obj/item/weapon/kitchen/utensil/knife) || istype(W, /obj/item/weapon/kitchenknife) || istype(W, /obj/item/weapon/kitchenknife/ritual)) user << "You use [W] to fashion a pipe out of the corn cob!" diff --git a/code/modules/hydroponics/hydro_tools.dm b/code/modules/hydroponics/hydro_tools.dm index be2158fee39..70cf1f9cf4b 100644 --- a/code/modules/hydroponics/hydro_tools.dm +++ b/code/modules/hydroponics/hydro_tools.dm @@ -203,7 +203,7 @@ /obj/item/weapon/plantspray icon = 'icons/obj/hydroponics.dmi' item_state = "spray" - flags = TABLEPASS | OPENCONTAINER | FPRINT | NOBLUDGEON + flags = OPENCONTAINER | NOBLUDGEON slot_flags = SLOT_BELT throwforce = 4 w_class = 2.0 @@ -255,7 +255,7 @@ icon = 'icons/obj/weapons.dmi' icon_state = "hoe" item_state = "hoe" - flags = FPRINT | TABLEPASS | CONDUCT | NOBLUDGEON + flags = CONDUCT | NOBLUDGEON force = 5.0 throwforce = 7.0 w_class = 2.0 @@ -270,7 +270,6 @@ name = "bottle of weedkiller" icon = 'icons/obj/chemical.dmi' icon_state = "bottle16" - flags = FPRINT | TABLEPASS var/toxicity = 0 var/weed_kill_str = 0 @@ -278,7 +277,6 @@ name = "bottle of glyphosate" icon = 'icons/obj/chemical.dmi' icon_state = "bottle16" - flags = FPRINT | TABLEPASS toxicity = 4 weed_kill_str = 2 @@ -286,7 +284,6 @@ name = "bottle of triclopyr" icon = 'icons/obj/chemical.dmi' icon_state = "bottle18" - flags = FPRINT | TABLEPASS toxicity = 6 weed_kill_str = 4 @@ -294,7 +291,6 @@ name = "bottle of 2,4-D" icon = 'icons/obj/chemical.dmi' icon_state = "bottle15" - flags = FPRINT | TABLEPASS toxicity = 8 weed_kill_str = 7 @@ -308,7 +304,7 @@ desc = "A small glass bottle. Can hold up to 10 units." icon = 'icons/obj/chemical.dmi' icon_state = "bottle16" - flags = FPRINT | TABLEPASS | OPENCONTAINER + flags = OPENCONTAINER possible_transfer_amounts = null w_class = 2.0 @@ -348,7 +344,7 @@ desc = "A very sharp axe blade upon a short fibremetal handle. It has a long history of chopping things, but now it is used for chopping wood." icon = 'icons/obj/weapons.dmi' icon_state = "hatchet" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT force = 12.0 w_class = 2.0 throwforce = 15.0 @@ -381,7 +377,7 @@ throw_speed = 1 throw_range = 3 w_class = 4.0 - flags = FPRINT | TABLEPASS | NOSHIELD + flags = NOSHIELD slot_flags = SLOT_BACK origin_tech = "materials=2;combat=2" attack_verb = list("chopped", "sliced", "cut", "reaped") diff --git a/code/modules/hydroponics/seed_machines.dm b/code/modules/hydroponics/seed_machines.dm index 837abe7211a..e2416733cc3 100644 --- a/code/modules/hydroponics/seed_machines.dm +++ b/code/modules/hydroponics/seed_machines.dm @@ -82,7 +82,7 @@ visible_message("\icon[src] [src] beeps and spits out [loaded_disk].") loaded_disk = null -/obj/machinery/botany/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/botany/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/seeds)) if(seed) user << "There is already a seed loaded." diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm index 948e78f96e9..a572b2c8d19 100644 --- a/code/modules/hydroponics/seeds.dm +++ b/code/modules/hydroponics/seeds.dm @@ -3,7 +3,6 @@ name = "packet of seeds" icon = 'icons/obj/seeds.dmi' icon_state = "seed" - flags = FPRINT | TABLEPASS w_class = 2.0 var/seed_type diff --git a/code/modules/hydroponics/vines.dm b/code/modules/hydroponics/vines.dm index 085229d417c..26819b231d9 100644 --- a/code/modules/hydroponics/vines.dm +++ b/code/modules/hydroponics/vines.dm @@ -32,7 +32,7 @@ master.growth_queue -= src ..() -/obj/effect/plantsegment/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/effect/plantsegment/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (!W || !user || !W.type) return switch(W.type) if(/obj/item/weapon/circular_saw) del src diff --git a/code/modules/jungle/jungle_plants.dm b/code/modules/jungle/jungle_plants.dm index db0cc017b75..3bc0315c581 100644 --- a/code/modules/jungle/jungle_plants.dm +++ b/code/modules/jungle/jungle_plants.dm @@ -27,7 +27,7 @@ A.loc = get_turf(src) */ -/obj/structure/bush/attackby(var/obj/I as obj, var/mob/user as mob) +/obj/structure/bush/attackby(var/obj/I as obj, var/mob/user as mob, params) //hatchets can clear away undergrowth if(istype(I, /obj/item/weapon/hatchet) && !stump) if(indestructable) diff --git a/code/modules/jungle/jungle_temple.dm b/code/modules/jungle/jungle_temple.dm index ca7b21c8cf8..138d1dc47d1 100644 --- a/code/modules/jungle/jungle_temple.dm +++ b/code/modules/jungle/jungle_temple.dm @@ -249,7 +249,7 @@ new /obj/item/weapon/storage/toolbox/electrical(C) if(prob(25)) - new /obj/item/weapon/cell(C) + new /obj/item/weapon/stock_parts/cell(C) if("coffin") new /obj/structure/closet/coffin(src.loc) diff --git a/code/modules/karma/karma.dm b/code/modules/karma/karma.dm index 12924560685..38c101b4370 100644 --- a/code/modules/karma/karma.dm +++ b/code/modules/karma/karma.dm @@ -52,42 +52,42 @@ var/list/karma_spenders = list() set name = "Award Karma" set desc = "Let the gods know whether someone's been nice. Can only be used once per round." set category = "Special Verbs" - + if(!ticker || !player_list.len) usr << "\red You can't award karma until the game has started." return - + if(ticker.current_state == GAME_STATE_PREGAME) usr << "\red You can't award karma until the game has started." - return + return var/list/karma_list = list("Cancel") - for(var/mob/M in player_list) if(M.client && M.mind) + for(var/mob/M in player_list) if(M.client && M.mind) var/special_role = M.mind.special_role if (special_role == "Wizard" || special_role == "Ninja" || special_role == "Syndicate" || special_role == "Syndicate Commando" || special_role == "Vox Raider" || special_role == "Alien") // Don't include special roles, because players use it to meta continue karma_list += M - + if(!karma_list.len || karma_list.len == 1) usr << "\red There's no-one to spend your karma on." return - + var/pickedmob = input("Who would you like to award Karma to?", "Award Karma", "Cancel") as null|mob in karma_list - + if(isnull(pickedmob)) return - + if(!istype(pickedmob, /mob)) usr << "\red That's not a mob." - return - + return + spend_karma(pickedmob) - -/mob/verb/spend_karma(var/mob/M) + +/mob/verb/spend_karma(var/mob/M) set name = "Award Karma to Player" set desc = "Let the gods know whether someone's been nice. Can only be used once per round." set category = "Special Verbs" - + if(!M) usr << "Please right click a mob to award karma directly, or use the 'Award Karma' verb to select a player from the player listing." return @@ -115,6 +115,9 @@ var/list/karma_spenders = list() if(!choice || choice == "Cancel") return if(choice == "Good" && !(src.client.karma_spent)) + if(src.client.karma_spent) + usr << "\red You've already spent your karma for the round." + return M.client.karma += 1 usr << "[choice] karma spent on [M.name]." src.client.karma_spent = 1 @@ -199,7 +202,7 @@ You've gained [totalkarma] total karma in your time here.
"} Unlock Vox -- 45KP
Unlock Slime People -- 45KP
"} - + if (2) // Karma Refunds var/list/refundable = list() var/list/purchased = checkpurchased() @@ -208,31 +211,31 @@ You've gained [totalkarma] total karma in your time here.
"} dat += "Refund Tajaran Ambassador -- 30KP
" if("Unathi Ambassador" in purchased) refundable += "Unathi Ambassador" - dat += "Refund Unathi Ambassador -- 30KP
" + dat += "Refund Unathi Ambassador -- 30KP
" if("Skrell Ambassador" in purchased) refundable += "Skrell Ambassador" - dat += "Refund Skrell Ambassador -- 30KP
" + dat += "Refund Skrell Ambassador -- 30KP
" if("Diona Ambassador" in purchased) refundable += "Diona Ambassador" - dat += "Refund Diona Ambassador -- 30KP
" + dat += "Refund Diona Ambassador -- 30KP
" if("Kidan Ambassador" in purchased) refundable += "Kidan Ambassador" - dat += "Refund Kidan Ambassador -- 30KP
" + dat += "Refund Kidan Ambassador -- 30KP
" if("Slime People Ambassador" in purchased) refundable += "Slime People Ambassador" - dat += "Refund Slime People Ambassador -- 30KP
" + dat += "Refund Slime People Ambassador -- 30KP
" if("Grey Ambassador" in purchased) refundable += "Grey Ambassador" - dat += "Refund Grey Ambassador -- 30KP
" + dat += "Refund Grey Ambassador -- 30KP
" if("Vox Ambassador" in purchased) refundable += "Vox Ambassador" dat += "Refund Vox Ambassador -- 30KP
" if("Customs Officer" in purchased) refundable += "Customs Officer" - dat += "Refund Customs Officer -- 30KP
" + dat += "Refund Customs Officer -- 30KP
" if("Nanotrasen Recruiter" in purchased) refundable += "Nanotrasen Recruiter" - dat += "Refund Nanotrasen Recruiter -- 10KP
" + dat += "Refund Nanotrasen Recruiter -- 10KP
" if(!refundable.len) dat += "You do not have any refundable karma purchases.
" @@ -342,10 +345,10 @@ You've gained [totalkarma] total karma in your time here.
"} message_admins("SQL ERROR during karmaspent updating (updating existing entry). Error: \[[err]\]\n") return else - usr << "You have been charged [cost] karma." - message_admins("[key_name(usr)] has been charged [cost] karma.") + usr << "You have been [refund ? "refunded" : "charged"] [cost] karma." + message_admins("[key_name(usr)] has been [refund ? "refunded" : "charged"] [cost] karma.") return - + /client/proc/karmarefund(var/type,var/name,var/cost) if(name == "Tajaran Ambassador") cost = 30 @@ -368,12 +371,12 @@ You've gained [totalkarma] total karma in your time here.
"} else if(name == "Nanotrasen Recruiter") cost = 10 else - usr << "\red That job is not refundable." + usr << "\red That job is not refundable." return - + var/DBQuery/query = dbcon.NewQuery("SELECT * FROM whitelist WHERE ckey='[usr.key]'") query.Execute() - + var/dbjob var/dbspecies var/dbckey @@ -381,7 +384,7 @@ You've gained [totalkarma] total karma in your time here.
"} dbckey = query.item[2] dbjob = query.item[3] dbspecies = query.item[4] - + if(dbckey) var/list/typelist = list() if(type == "job") @@ -389,8 +392,8 @@ You've gained [totalkarma] total karma in your time here.
"} else if(type == "species") typelist = text2list(dbspecies,",") else - usr << "\red Type [type] is not a valid column." - + usr << "\red Type [type] is not a valid column." + if(name in typelist) typelist -= name var/newtypelist = list2text(typelist,",") @@ -406,14 +409,14 @@ You've gained [totalkarma] total karma in your time here.
"} karmacharge(text2num(cost),1) else usr << "\red You have not bought [name]." - + else - usr << "\red Your ckey ([dbckey]) was not found." - + usr << "\red Your ckey ([dbckey]) was not found." + /client/proc/checkpurchased(var/name = null) // If the first parameter is null, return a full list of purchases var/DBQuery/query = dbcon.NewQuery("SELECT * FROM whitelist WHERE ckey='[usr.key]'") - query.Execute() - + query.Execute() + var/dbjob var/dbspecies var/dbckey @@ -421,7 +424,7 @@ You've gained [totalkarma] total karma in your time here.
"} dbckey = query.item[2] dbjob = query.item[3] dbspecies = query.item[4] - + if(dbckey) var/list/joblist = text2list(dbjob,",") var/list/specieslist = text2list(dbspecies,",") @@ -434,4 +437,4 @@ You've gained [totalkarma] total karma in your time here.
"} else return combinedlist else - return 0 + return 0 diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index ec39b53741e..9df91110429 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -28,7 +28,7 @@ I.loc = src update_icon() -/obj/structure/bookcase/attackby(obj/O as obj, mob/user as mob) +/obj/structure/bookcase/attackby(obj/O as obj, mob/user as mob, params) if(istype(O, /obj/item/weapon/book) || istype(O, /obj/item/weapon/spellbook)) user.drop_item() O.loc = src @@ -149,7 +149,6 @@ throw_speed = 1 throw_range = 5 w_class = 3 //upped to three because books are, y'know, pretty big. (and you could hide them inside eachother recursively forever) - flags = FPRINT | TABLEPASS attack_verb = list("bashed", "whacked", "educated") autoignition_temperature = AUTOIGNITION_PAPER @@ -179,7 +178,7 @@ else user << "This book is completely blank!" -/obj/item/weapon/book/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/book/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(carved) if(!store) if(W.w_class < 3) @@ -274,7 +273,6 @@ throw_speed = 1 throw_range = 5 w_class = 1.0 - flags = FPRINT | TABLEPASS var/obj/machinery/librarycomp/computer // Associated computer - Modes 1 to 3 use this var/obj/item/weapon/book/book // Currently scanned book var/mode = 0 // 0 - Scan only, 1 - Scan and Set Buffer, 2 - Scan and Attempt to Check In, 3 - Scan and Attempt to Add to Inventory diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index c1fdb193485..c9d656a05ff 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -237,9 +237,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f user << browse(dat, "window=library") onclose(user, "library") -/obj/machinery/librarycomp/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (src.density && istype(W, /obj/item/weapon/card/emag)) - src.emagged = 1 +/obj/machinery/librarycomp/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/barcodescanner)) var/obj/item/weapon/barcodescanner/scanner = W scanner.computer = src @@ -248,6 +246,10 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f V.show_message("[src] lets out a low, short blip.", 2) else ..() + +/obj/machinery/librarycomp/emag_act(user as mob) + if (src.density) + src.emagged = 1 /obj/machinery/librarycomp/Topic(href, href_list) if(..()) @@ -300,9 +302,9 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f if(checkoutperiod < 1) checkoutperiod = 1 if(href_list["editbook"]) - buffer_book = copytext(sanitize(input("Enter the book's title:") as text|null),1,MAX_MESSAGE_LEN) + buffer_book = sanitize(copytext(input("Enter the book's title:") as text|null,1,MAX_MESSAGE_LEN)) if(href_list["editmob"]) - buffer_mob = copytext(sanitize(input("Enter the recipient's name:") as text|null),1,MAX_NAME_LEN) + buffer_mob = sanitize(copytext(input("Enter the recipient's name:") as text|null,1,MAX_NAME_LEN)) if(href_list["checkout"]) var/datum/borrowbook/b = new /datum/borrowbook b.bookname = sanitize(buffer_book) @@ -317,7 +319,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f var/obj/item/weapon/book/b = locate(href_list["delbook"]) inventory.Remove(b) if(href_list["setauthor"]) - var/newauthor = copytext(sanitize(input("Enter the author's name: ") as text|null),1,MAX_MESSAGE_LEN) + var/newauthor = sanitize(copytext(input("Enter the author's name: ") as text|null,1,MAX_MESSAGE_LEN)) if(newauthor) scanner.cache.author = newauthor if(href_list["setcategory"]) @@ -402,7 +404,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f density = 1 var/obj/item/weapon/book/cache // Last scanned book -/obj/machinery/libraryscanner/attackby(var/obj/O as obj, var/mob/user as mob) +/obj/machinery/libraryscanner/attackby(var/obj/O as obj, var/mob/user as mob, params) if(istype(O, /obj/item/weapon/book)) user.drop_item() O.loc = src @@ -452,7 +454,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f anchored = 1 density = 1 -/obj/machinery/bookbinder/attackby(var/obj/O as obj, var/mob/user as mob) +/obj/machinery/bookbinder/attackby(var/obj/O as obj, var/mob/user as mob, params) if(istype(O, /obj/item/weapon/paper)) user.drop_item() O.loc = src diff --git a/code/modules/media/broadcast/transmitters/broadcast.dm b/code/modules/media/broadcast/transmitters/broadcast.dm index 772003efd0e..63e7c933f4e 100644 --- a/code/modules/media/broadcast/transmitters/broadcast.dm +++ b/code/modules/media/broadcast/transmitters/broadcast.dm @@ -48,7 +48,7 @@ broadcast() // Bzzt /* -/obj/machinery/media/transmitter/broadcast/attackby(var/obj/item/W, mob/user) +/obj/machinery/media/transmitter/broadcast/attackby(var/obj/item/W, mob/user, params) if(istype(W, /obj/item/device/multitool)) update_multitool_menu(user) return 1 diff --git a/code/modules/media/jukebox.dm b/code/modules/media/jukebox.dm index 3605e929f7c..e0fbf78ca6d 100644 --- a/code/modules/media/jukebox.dm +++ b/code/modules/media/jukebox.dm @@ -155,7 +155,7 @@ var/global/loopModeNames=list( popup.open() -/obj/machinery/media/jukebox/attackby(obj/item/W, mob/user) +/obj/machinery/media/jukebox/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/weapon/card/emag)) current_song=0 if(!emagged) diff --git a/code/modules/media/mediamanager.dm b/code/modules/media/mediamanager.dm index 46103722c68..aa52f5c80a2 100644 --- a/code/modules/media/mediamanager.dm +++ b/code/modules/media/mediamanager.dm @@ -6,8 +6,36 @@ * Rewritten (except for player HTML) by N3X15 ***********************/ -// Open up WMP and play musique. -// TODO: Convert to VLC for cross-platform and ogg support. - N3X +// Open up VLC and play musique. +// Converted to VLC for cross-platform and ogg support. - N3X +var/const/PLAYER_HTML={" + + + +"} + +/* OLD, DO NOT USE. CONTROLS.CURRENTPOSITION IS BROKEN. var/const/PLAYER_HTML={" "} +*/ // Hook into the events we desire. /hook_handler/soundmanager diff --git a/code/modules/mining/abandonedcrates.dm b/code/modules/mining/abandonedcrates.dm index 504234d9886..7ca5d9496d7 100644 --- a/code/modules/mining/abandonedcrates.dm +++ b/code/modules/mining/abandonedcrates.dm @@ -50,7 +50,7 @@ if(15) new/obj/item/clothing/under/chameleon(src) for(var/i = 0, i < 7, i++) - new/obj/item/clothing/tie/horrible(src) + new/obj/item/clothing/accessory/horrible(src) if(16) new/obj/item/clothing/under/shorts(src) new/obj/item/clothing/under/shorts/red(src) @@ -91,7 +91,7 @@ else return ..() -/obj/structure/closet/crate/secure/loot/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/closet/crate/secure/loot/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(locked) if (istype(W, /obj/item/weapon/card/emag)) user << "The crate unlocks!" diff --git a/code/modules/mining/coins.dm b/code/modules/mining/coins.dm index a65916bff65..cc1e966ff46 100644 --- a/code/modules/mining/coins.dm +++ b/code/modules/mining/coins.dm @@ -75,7 +75,7 @@ credits = 20 -/obj/item/weapon/coin/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/coin/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/stack/cable_coil)) var/obj/item/stack/cable_coil/CC = W if(string_attached) diff --git a/code/modules/mining/drilling/drill.dm b/code/modules/mining/drilling/drill.dm index 65fc72f1636..7732e622cbf 100644 --- a/code/modules/mining/drilling/drill.dm +++ b/code/modules/mining/drilling/drill.dm @@ -33,7 +33,7 @@ var/obj/item/weapon/stock_parts/matter_bin/storage var/obj/item/weapon/stock_parts/micro_laser/cutter var/obj/item/weapon/stock_parts/capacitor/cellmount - var/obj/item/weapon/cell/cell + var/obj/item/weapon/stock_parts/cell/cell //Flags var/need_update_field = 0 @@ -140,7 +140,7 @@ /obj/machinery/mining/drill/attack_ai(var/mob/user as mob) return src.attack_hand(user) -/obj/machinery/mining/drill/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/mining/drill/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/screwdriver)) if(active) return open = !open @@ -195,7 +195,7 @@ cellmount = W user << "You install \the [W]." return - else if(istype(W,/obj/item/weapon/cell)) + else if(istype(W,/obj/item/weapon/stock_parts/cell)) if(cell) user << "The drill already has a cell installed." else @@ -323,7 +323,7 @@ icon_state = "mining_brace" var/obj/machinery/mining/drill/connected -/obj/machinery/mining/brace/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/mining/brace/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/wrench)) if(istype(get_turf(src),/turf/space)) diff --git a/code/modules/mining/equipment_locker.dm b/code/modules/mining/equipment_locker.dm index 1a0315b957d..61569fb57d5 100644 --- a/code/modules/mining/equipment_locker.dm +++ b/code/modules/mining/equipment_locker.dm @@ -228,7 +228,7 @@ updateUsrDialog() return -/obj/machinery/mineral/equipment_locker/attackby(obj/item/I as obj, mob/user as mob) +/obj/machinery/mineral/equipment_locker/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/weapon/mining_voucher)) RedeemVoucher(I, user) return @@ -285,7 +285,7 @@ icon_state = "data" var/points = 500 -/obj/item/weapon/card/mining_point_card/attackby(obj/item/I as obj, mob/user as mob) +/obj/item/weapon/card/mining_point_card/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/weapon/card/id)) if(points) var/obj/item/weapon/card/id/C = I @@ -324,7 +324,7 @@ var/list/L = list() for(var/obj/item/device/radio/beacon/B in world) var/turf/T = get_turf(B) - if(T.z == 1) + if((T.z in config.station_levels)) L += B if(!L.len) user << "The [src.name] failed to create a wormhole." @@ -484,7 +484,7 @@ projectilesound = 'sound/weapons/Gunshot4.ogg' wanted_objects = list(/obj/item/weapon/ore) -/mob/living/simple_animal/hostile/mining_drone/attackby(obj/item/I as obj, mob/user as mob) +/mob/living/simple_animal/hostile/mining_drone/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/W = I if(W.welding && !stat) diff --git a/code/modules/mining/laborcamp/laborshuttle.dm b/code/modules/mining/laborcamp/laborshuttle.dm index c9926d429a6..4b293e71350 100644 --- a/code/modules/mining/laborcamp/laborshuttle.dm +++ b/code/modules/mining/laborcamp/laborshuttle.dm @@ -99,7 +99,7 @@ proc/move_labor_shuttle() //TODO: Security Access only; add moving the shuttle t else usr << "\blue Shuttle is already moving." -/obj/machinery/computer/labor_shuttle/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/computer/labor_shuttle/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/card/emag)) src.req_access = list() diff --git a/code/modules/mining/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm index 0e0889bc637..e4abfbdbcbc 100644 --- a/code/modules/mining/laborcamp/laborstacker.dm +++ b/code/modules/mining/laborcamp/laborstacker.dm @@ -12,14 +12,15 @@ var/obj/item/weapon/card/id/prisoner/inserted_id var/obj/machinery/door/airlock/release_door var/door_tag = "prisonshuttle" - var/obj/item/device/radio/Radio //needed to send messages to sec radio var/use_release_door = 0 + var/obj/item/device/radio/intercom/announcer /obj/machinery/mineral/labor_claim_console/New() ..() - Radio = new/obj/item/device/radio(src) - Radio.listening = 0 + announcer = new /obj/item/device/radio/intercom(null) + announcer.config(list("Security" = 0)) + spawn(7) src.machine = locate(/obj/machinery/mineral/stacking_machine, get_step(src, machinedir)) var/t @@ -60,12 +61,13 @@ user << browse("[dat]", "window=console_stacking_machine") -/obj/machinery/mineral/labor_claim_console/attackby(obj/item/I as obj, mob/user as mob) +/obj/machinery/mineral/labor_claim_console/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/weapon/card/id)) return attack_hand(user) - else if(istype(I, /obj/item/weapon/card/emag)) - return emag(user) ..() + +/obj/machinery/mineral/labor_claim_console/emag_act(user as mob) + emag(user) /obj/machinery/mineral/labor_claim_console/proc/emag(mob/user as mob) if(!emagged) @@ -102,8 +104,8 @@ else if(shuttle.location == 1) if (shuttle.moving_status == SHUTTLE_IDLE) - Radio.set_frequency(SEC_FREQ) - Radio.talk_into(src, "[inserted_id.registered_name] has returned to the station. Minerals and Prisoner ID card ready for retrieval.", SEC_FREQ) + var/message = "[inserted_id.registered_name] has returned to the station. Minerals and Prisoner ID card ready for retrieval." + announcer.autosay(message, "Labor Camp Controller", "Security") usr << "Shuttle received message and will be sent shortly." shuttle.launch() else @@ -130,7 +132,7 @@ /obj/machinery/mineral/stacking_machine/laborstacker var/points = 0 //The unclaimed value of ore stacked. Value for each ore loosely relative to its rarity. - var/list/ore_values = list(("glass" = 1), ("metal" = 2), ("solid plasma" = 20), ("plasteel" = 23), ("reinforced glass" = 4), ("gold" = 20), ("silver" = 20), ("uranium" = 20), ("diamond" = 25), ("bananium" = 50)) + var/list/ore_values = list(("glass" = 1), ("metal" = 2), ("iron" = 3), ("solid plasma" = 20), ("plasteel" = 23), ("reinforced glass" = 4), ("gold" = 20), ("silver" = 20), ("uranium" = 20), ("diamond" = 25), ("bananium" = 50)) /obj/machinery/mineral/stacking_machine/laborstacker/proc/get_ore_values() var/dat = "" @@ -154,6 +156,17 @@ S.loc = output.loc else O.loc = output.loc + + //Output amounts that are past stack_amt. + for(var/sheet in stack_storage) + if(stack_storage[sheet] >= stack_amt) + var/stacktype = stack_paths[sheet] + var/obj/item/stack/sheet/S = new stacktype (get_turf(output)) + S.amount = stack_amt + stack_storage[sheet] -= stack_amt + + console.updateUsrDialog() + return /**********************Point Lookup Console**************************/ @@ -168,7 +181,7 @@ /obj/machinery/mineral/labor_points_checker/attack_hand(mob/user) user.examine(src) -/obj/machinery/mineral/labor_points_checker/attackby(obj/item/I as obj, mob/user as mob) +/obj/machinery/mineral/labor_points_checker/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/weapon/card/id)) if(istype(I, /obj/item/weapon/card/id/prisoner)) var/obj/item/weapon/card/id/prisoner/prisoner_id = I diff --git a/code/modules/mining/manufacturing.dm b/code/modules/mining/manufacturing.dm index 07a00bb7561..52274b0ea32 100644 --- a/code/modules/mining/manufacturing.dm +++ b/code/modules/mining/manufacturing.dm @@ -293,7 +293,7 @@ src.updateUsrDialog() - attackby(obj/item/weapon/W as obj, mob/user as mob) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) var/load = 0 if(istype(W, /obj/item/weapon/ore/)) for(var/mob/O in viewers(user, null)) O.show_message(text("\blue [] loads [] into the [].", user, W, src), 1) @@ -317,7 +317,7 @@ //else if (istype(W, /obj/item/weapon/plant/wheat/metal)) // new /obj/item/weapon/ore/iron(src) // load = 2 - /*else if(istype(W, /obj/item/weapon/cable_coil/)) + /*else if(istype(W, /obj/item/stack/cable_coil/)) for(var/mob/O in viewers(user, null)) O.show_message(text("\blue [] loads [] into the [].", user, W, src), 1) for (var/amt = W:amount, amt > 0, amt--) new /obj/item/weapon/ore/silver(src) @@ -374,13 +374,13 @@ else ..() if (load == 1) - user.u_equip(W) + user.unEquip(W) W.loc = src if ((user.client && user.s_active != src)) user.client.screen -= W W.dropped() else if (load == 2) - user.u_equip(W) + user.unEquip(W) W.dropped() if ((user.client && user.s_active != src)) user.client.screen -= W @@ -685,7 +685,7 @@ /* /datum/manufacture/cable name = "Electrical Cable Piece" - item = /obj/item/weapon/cable_coil/cut + item = /obj/item/stack/cable_coil/cut cost1 = /obj/item/weapon/ore/silver cname1 = "Silver" amount1 = 1 @@ -814,7 +814,7 @@ /datum/manufacture/powercell name = "Power Cell" - item = /obj/item/weapon/cell + item = /obj/item/weapon/stock_parts/cell cost1 = /obj/item/weapon/ore/iron cname1 = "Iron" amount1 = 4 diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index b7d8ac6c05e..f6c03ee308b 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -52,22 +52,25 @@ name = "pickaxe" icon = 'icons/obj/items.dmi' icon_state = "pickaxe" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT force = 15.0 - throwforce = 4.0 + throwforce = 10.0 item_state = "pickaxe" w_class = 4.0 m_amt = 3750 //one sheet, but where can you make them? var/digspeed = 40 //moving the delay to an item var so R&D can make improved picks. --NEO origin_tech = "materials=1;engineering=1" attack_verb = list("hit", "pierced", "sliced", "attacked") - var/drill_sound = 'sound/weapons/Genhit.ogg' + var/list/digsound = list('sound/effects/picaxe1.ogg','sound/effects/picaxe2.ogg','sound/effects/picaxe3.ogg') var/drill_verb = "picking" sharp = 1 var/excavation_amount = 100 + proc/playDigSound() + playsound(src, pick(digsound),20,1) + hammer name = "sledgehammer" //icon_state = "sledgehammer" Waiting on sprite @@ -86,6 +89,8 @@ icon_state = "handdrill" item_state = "jackhammer" digspeed = 30 + hitsound = 'sound/weapons/drill.ogg' + digsound = list('sound/weapons/drill.ogg') origin_tech = "materials=2;powerstorage=3;engineering=2" desc = "Yours is the drill that will pierce through the rock walls." @@ -94,6 +99,8 @@ icon_state = "jackhammer" item_state = "jackhammer" digspeed = 15 //faster than drill, but cannot dig + hitsound = 'sound/weapons/sonic_jackhammer.ogg' + digsound = list('sound/weapons/sonic_jackhammer.ogg') origin_tech = "materials=3;powerstorage=2;engineering=2" desc = "Cracks rocks with sonic blasts, perfect for killing cave lizards." @@ -112,6 +119,8 @@ w_class = 3.0 //it is smaller than the pickaxe damtype = "fire" digspeed = 20 //Can slice though normal walls, all girders, or be used in reinforced wall deconstruction/ light thermite on fire + hitsound = 'sound/weapons/plasma_cutter.ogg' + digsound = list('sound/weapons/plasma_cutter.ogg') origin_tech = "materials=4;plasmatech=3;engineering=3" desc = "A rock cutter that uses bursts of hot plasma. You could use it to cut limbs off of xenos! Or, you know, mine stuff." @@ -129,6 +138,8 @@ item_state = "jackhammer" digspeed = 5 //Digs through walls, girders, and can dig up sand origin_tech = "materials=6;powerstorage=4;engineering=5" + hitsound = 'sound/weapons/drill.ogg' + digsound = list('sound/weapons/drill.ogg') desc = "Yours is the drill that will pierce the heavens!" traitor //Pocket-sized traitor diamond drill. @@ -143,6 +154,8 @@ icon_state = "jackhammer" item_state = "jackhammer" digspeed = 15 + hitsound = 'sound/weapons/drill.ogg' + digsound = list('sound/weapons/drill.ogg') desc = "" /*****************************Shovel********************************/ @@ -152,7 +165,7 @@ desc = "A large tool for digging and moving dirt." icon = 'icons/obj/items.dmi' icon_state = "shovel" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT force = 8.0 throwforce = 4.0 diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index b315ae31e5b..8ab42b7ae1c 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -103,7 +103,7 @@ scan_state = "rock_[mineral.name][rand(1,3)]" //Not even going to touch this pile of spaghetti - attackby(obj/item/weapon/W as obj, mob/user as mob) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") usr << "\red You don't have the dexterity to do this!" @@ -137,7 +137,7 @@ return last_act = world.time - playsound(user, P.drill_sound, 20, 1) + P.playDigSound() //handle any archaeological finds we might uncover var/fail_message @@ -279,6 +279,7 @@ M.apply_effect(25, IRRADIATE) var/turf/simulated/floor/plating/airless/asteroid/N = ChangeTurf(/turf/simulated/floor/plating/airless/asteroid) + playsound(src, 'sound/effects/break_stone.ogg', 50, 1) //beautiful destruction N.fullUpdateMineralOverlays() if(rand(1,750) == 1) @@ -419,7 +420,7 @@ gets_dug() return -/turf/simulated/floor/plating/airless/asteroid/attackby(obj/item/weapon/W as obj, mob/user as mob) +/turf/simulated/floor/plating/airless/asteroid/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(!W || !user) return 0 @@ -434,7 +435,7 @@ return user << "\red You start digging." - playsound(loc, 'sound/effects/rustle1.ogg', 50, 1) //russle sounds sounded better + playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1) //FUCK YO RUSTLE I GOT'S THE DIGS SOUND HERE sleep(40) if ((user.loc == T && user.get_active_hand() == W)) @@ -451,7 +452,7 @@ return user << "\red You start digging." - playsound(loc, 'sound/effects/rustle1.ogg', 50, 1) //russle sounds sounded better + playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1) //FUCK YO RUSTLE I GOT'S THE DIGS SOUND HERE sleep(30) if ((user.loc == T && user.get_active_hand() == W)) @@ -468,7 +469,7 @@ return user << "\red You start digging." - playsound(loc, 'sound/effects/rustle1.ogg', 50, 1) //russle sounds sounded better + playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1) //FUCK YO RUSTLE I GOT'S THE DIGS SOUND HERE sleep(0) if ((user.loc == T && user.get_active_hand() == W)) diff --git a/code/modules/mining/money_bag.dm b/code/modules/mining/money_bag.dm index fbcca4984bb..3b94f63673b 100644 --- a/code/modules/mining/money_bag.dm +++ b/code/modules/mining/money_bag.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/storage.dmi' name = "Money bag" icon_state = "moneybag" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT force = 10.0 throwforce = 2.0 w_class = 4.0 @@ -72,7 +72,7 @@ */ user << browse("[dat]", "window=moneybag") -/obj/item/weapon/moneybag/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/moneybag/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if (istype(W, /obj/item/weapon/coin)) var/obj/item/weapon/coin/C = W diff --git a/code/modules/mining/ore.dm b/code/modules/mining/ore.dm index fd3598ae985..78e0509cc0c 100644 --- a/code/modules/mining/ore.dm +++ b/code/modules/mining/ore.dm @@ -84,9 +84,9 @@ /obj/item/weapon/ore/New() pixel_x = rand(0,16)-8 pixel_y = rand(0,8)-8 - if(src.z == 5) score_oremined++ //When ore spawns, increment score. Only include ore spawned on mining asteroid (No Clown Planet) + if(src.z == ASTEROID_Z) score_oremined++ //When ore spawns, increment score. Only include ore spawned on mining asteroid (No Clown Planet) -/obj/item/weapon/ore/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/ore/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/device/core_sampler)) var/obj/item/device/core_sampler/C = W C.sample_item(src, user) diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm index d3ecc25ec92..ddb82b4f6e4 100644 --- a/code/modules/mining/satchel_ore_boxdm.dm +++ b/code/modules/mining/satchel_ore_boxdm.dm @@ -18,9 +18,9 @@ var/amt_strange = 0 var/last_update = 0 -/obj/structure/ore_box/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/ore_box/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/ore)) - user.u_equip(W) + user.unEquip(W) src.contents += W if (istype(W, /obj/item/weapon/storage)) var/obj/item/weapon/storage/S = W diff --git a/code/modules/mining/surprises/tg.dm b/code/modules/mining/surprises/tg.dm index 5c9b6b201af..e80d3a87115 100644 --- a/code/modules/mining/surprises/tg.dm +++ b/code/modules/mining/surprises/tg.dm @@ -130,7 +130,7 @@ spawntypes = list( /obj/item/weapon/pickaxe/plasmacutter=1, /obj/machinery/shieldgen=1, - /obj/item/weapon/cell/hyper=1 + /obj/item/weapon/stock_parts/cell/hyper=1 ) fluffitems = list( /obj/structure/table/reinforced=2, diff --git a/code/modules/mob/dead/observer/login.dm b/code/modules/mob/dead/observer/login.dm index ce0dbe3d57f..e5041e959c1 100644 --- a/code/modules/mob/dead/observer/login.dm +++ b/code/modules/mob/dead/observer/login.dm @@ -1,2 +1,5 @@ /mob/dead/observer/Login() - ..() \ No newline at end of file + ..() + if (ghostimage) + ghostimage.icon_state = src.icon_state + updateghostimages() \ No newline at end of file diff --git a/code/modules/mob/dead/observer/logout.dm b/code/modules/mob/dead/observer/logout.dm index cf51df634eb..969f6574b9b 100644 --- a/code/modules/mob/dead/observer/logout.dm +++ b/code/modules/mob/dead/observer/logout.dm @@ -1,4 +1,6 @@ /mob/dead/observer/Logout() + if (client) + client.images -= ghost_darkness_images ..() spawn(0) if(src && !key) //we've transferred to another mob. This ghost should be deleted. diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 4be7623c8ff..87b60348e03 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -1,6 +1,7 @@ #define GHOST_CAN_REENTER 1 #define GHOST_IS_OBSERVER 2 +var/list/image/ghost_darkness_images = list() //this is a list of images for things ghosts should still be able to see when they toggle darkness /mob/dead/observer name = "ghost" @@ -24,6 +25,10 @@ var/atom/movable/following = null var/medHUD = 0 var/secHUD = 0 + var/anonsay = 0 + var/image/ghostimage = null //this mobs ghost image, for deleting and stuff + var/ghostvision = 1 //is the ghost able to see things humans can't? + var/seedarkness = 1 /mob/dead/observer/New(var/mob/body=null, var/flags=1) sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF @@ -40,6 +45,10 @@ stat = DEAD + ghostimage = image(src.icon,src,src.icon_state) + ghost_darkness_images |= ghostimage + updateallghostimages() + var/turf/T if(ismob(body)) T = get_turf(body) //Where is the body located? @@ -77,6 +86,14 @@ real_name = name ..() +/mob/dead/observer/Destroy() + if (ghostimage) + ghost_darkness_images -= ghostimage + qdel(ghostimage) + ghostimage = null + updateallghostimages() + ..() + /mob/dead/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) return 1 /* @@ -113,7 +130,7 @@ Works together with spawning an observer, noted above. for(var/mob/living/carbon/human/patient in oview(M, 14)) C.images += patient.hud_list[HEALTH_HUD] C.images += patient.hud_list[STATUS_HUD_OOC] - + /mob/dead/proc/process_secHUD(var/mob/M) var/client/C = M.client for(var/mob/living/carbon/human/target in oview(M, 14)) @@ -460,21 +477,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp src << "\blue Heat Capacity: [round(environment.heat_capacity(),0.1)]" -/mob/dead/observer/verb/toggle_sight() - set name = "Toggle Sight" - set category = "Ghost" - - switch(see_invisible) - if(SEE_INVISIBLE_OBSERVER_AI_EYE) - see_invisible = SEE_INVISIBLE_OBSERVER_NOOBSERVERS - usr << "You no longer see other observers or the AI eye." - if(SEE_INVISIBLE_OBSERVER_NOOBSERVERS) - see_invisible = SEE_INVISIBLE_OBSERVER_NOLIGHTING - usr << "You no longer see darkness." - else - see_invisible = SEE_INVISIBLE_OBSERVER_AI_EYE - usr << "You again see everything." - /mob/dead/observer/verb/view_manfiest() set name = "View Crew Manifest" set category = "Ghost" @@ -491,6 +493,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp return ..() + if (href_list["track"]) + var/mob/target = locate(href_list["track"]) in mob_list + if(target) + ManualFollow(target) + if (href_list["follow"]) var/mob/target = locate(href_list["follow"]) in mob_list var/mob/A = usr; @@ -532,3 +539,52 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp following = null ..() //END TELEPORT HREF CODE + +/mob/dead/observer/verb/toggle_anonsay() + set category = "Ghost" + set name = "Toggle Anonymous Chat" + set desc = "Toggles showing your key in dead chat." + + src.anonsay = !src.anonsay + if(anonsay) + src << "Your key won't be shown when you speak in dead chat." + else + src << "Your key will be publicly visible again." + +/mob/dead/observer/verb/toggle_ghostsee() + set name = "Toggle Ghost Vision" + set desc = "Toggles your ability to see things only ghosts can see, like other ghosts" + set category = "Ghost" + ghostvision = !(ghostvision) + updateghostsight() + usr << "You [(ghostvision?"now":"no longer")] have ghost vision." + +/mob/dead/observer/verb/toggle_darkness() + set name = "Toggle Darkness" + set category = "Ghost" + seedarkness = !(seedarkness) + updateghostsight() + +/mob/dead/observer/proc/updateghostsight() + if (!seedarkness) + see_invisible = SEE_INVISIBLE_OBSERVER_NOLIGHTING + else + see_invisible = SEE_INVISIBLE_OBSERVER + if (!ghostvision) + see_invisible = SEE_INVISIBLE_LIVING; + updateghostimages() + +/proc/updateallghostimages() + for (var/mob/dead/observer/O in player_list) + O.updateghostimages() + +/mob/dead/observer/proc/updateghostimages() + if (!client) + return + if (seedarkness || !ghostvision) + client.images -= ghost_darkness_images + else + //add images for the 60inv things ghosts can normally see when darkness is enabled so they can see them now + client.images |= ghost_darkness_images + if (ghostimage) + client.images -= ghostimage //remove ourself \ No newline at end of file diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm index 07e8d5c6dee..25c712354ce 100644 --- a/code/modules/mob/emote.dm +++ b/code/modules/mob/emote.dm @@ -1,3 +1,18 @@ +#define EMOTE_COOLDOWN 50 //Time in deciseconds that the cooldown lasts + +//Emote Cooldown System (it's so simple!) +/mob/proc/handle_emote_CD() + if(emote_cd == 2) return 1 // Cooldown emotes were disabled by an admin, prevent use + if(src.emote_cd == 1) return 1 // Already on CD, prevent use + + src.emote_cd = 1 // Starting cooldown + spawn(EMOTE_COOLDOWN) + if(emote_cd == 2) return 1 // Don't reset if cooldown emotes were disabled by an admin during the cooldown + src.emote_cd = 0 // Cooldown complete, ready for more! + + return 0 // Proceed with emote +//--FalseIncarnate + // All mobs should have custom emote, really.. /mob/proc/custom_emote(var/m_type=1,var/message = null) @@ -10,7 +25,7 @@ var/input if(!message) - input = copytext(sanitize(input(src,"Choose an emote to display.") as text|null),1,MAX_MESSAGE_LEN) + input = sanitize(copytext(input(src,"Choose an emote to display.") as text|null,1,MAX_MESSAGE_LEN)) else input = message if(input) @@ -85,7 +100,7 @@ var/input if(!message) - input = copytext(sanitize(input(src, "Choose an emote to display.") as text|null), 1, MAX_MESSAGE_LEN) + input = sanitize(copytext(input(src, "Choose an emote to display.") as text|null, 1, MAX_MESSAGE_LEN)) else input = message diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm new file mode 100644 index 00000000000..f63566a0483 --- /dev/null +++ b/code/modules/mob/hear_say.dm @@ -0,0 +1,215 @@ +// At minimum every mob has a hear_say proc. + +/mob/proc/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "",var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol) + if(!client) + return + + if(speaker && !speaker.client && istype(src,/mob/dead/observer) && client.prefs.toggles & CHAT_GHOSTEARS && !speaker in view(src)) + //Does the speaker have a client? It's either random stuff that observers won't care about (Experiment 97B says, 'EHEHEHEHEHEHEHE') + //Or someone snoring. So we make it where they won't hear it. + return + + //make sure the air can transmit speech - hearer's side + var/turf/T = get_turf(src) + if ((T) && (!(istype(src, /mob/dead/observer)))) //Ghosts can hear even in vacuum. + var/datum/gas_mixture/environment = T.return_air() + var/pressure = (environment)? environment.return_pressure() : 0 + if(pressure < SOUND_MINIMUM_PRESSURE && get_dist(speaker, src) > 1) + return + + if (pressure < ONE_ATMOSPHERE*0.4) //sound distortion pressure, to help clue people in that the air is thin, even if it isn't a vacuum yet + italics = 1 + sound_vol *= 0.5 //muffle the sound a bit, so it's like we're actually talking through contact + + if(sleeping || stat == 1) + hear_sleep(message) + return + + //non-verbal languages are garbled if you can't see the speaker. Yes, this includes if they are inside a closet. + if (language && (language.flags & NONVERBAL)) + if (!speaker || (src.sdisabilities & BLIND || src.blinded) || !(speaker in view(src))) + message = stars(message) + + if(!(language && (language.flags & INNATE))) // skip understanding checks for INNATE languages + if(!say_understands(speaker,language)) + if(istype(speaker,/mob/living/simple_animal)) + var/mob/living/simple_animal/S = speaker + message = pick(S.speak) + else + if(language) + message = language.scramble(message) + else + message = stars(message) + + var/speaker_name = speaker.name + if(istype(speaker, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = speaker + speaker_name = H.GetVoice() + + if(italics) + message = "[message]" + + var/track = null + if(istype(src, /mob/dead/observer)) + if(italics && client.prefs.toggles & CHAT_GHOSTRADIO) + return + if(speaker_name != speaker.real_name && speaker.real_name) + speaker_name = "[speaker.real_name] ([speaker_name])" + track = "(follow) " + if(client.prefs.toggles & CHAT_GHOSTEARS && speaker in view(src)) + message = "[message]" + + if(sdisabilities & DEAF || ear_deaf) + if(!language || !(language.flags & INNATE)) // INNATE is the flag for audible-emote-language, so we don't want to show an "x talks but you cannot hear them" message if it's set + if(speaker == src) + src << "You cannot hear yourself speak!" + else + src << "[speaker_name][alt_name] talks but you cannot hear \him." + else + if(language) + src << "[speaker_name][alt_name] [track][language.format_message(message, verb)]" + else + src << "[speaker_name][alt_name] [track][verb], \"[message]\"" + if (speech_sound && (get_dist(speaker, src) <= world.view && src.z == speaker.z)) + var/turf/source = speaker? get_turf(speaker) : get_turf(src) + src.playsound_local(source, speech_sound, sound_vol, 1) + + +/mob/proc/hear_radio(var/message, var/verb="says", var/datum/language/language=null, var/part_a, var/part_b, var/mob/speaker = null, var/hard_to_hear = 0, var/vname ="") + + if(!client) + return + + if(sleeping || stat==1) //If unconscious or sleeping + hear_sleep(message) + return + + var/track = null + + //non-verbal languages are garbled if you can't see the speaker. Yes, this includes if they are inside a closet. + if (language && (language.flags & NONVERBAL)) + if (!speaker || (src.sdisabilities & BLIND || src.blinded) || !(speaker in view(src))) + message = stars(message) + + if(!(language && (language.flags & INNATE))) // skip understanding checks for INNATE languages + if(!say_understands(speaker,language)) + if(istype(speaker,/mob/living/simple_animal)) + var/mob/living/simple_animal/S = speaker + if(S.speak && S.speak.len) + message = pick(S.speak) + else + return + else + if(language) + message = language.scramble(message) + else + message = stars(message) + + if(hard_to_hear) + message = stars(message) + + var/speaker_name = speaker.name + + if(vname) + speaker_name = vname + + if(istype(speaker, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = speaker + if(H.voice) + speaker_name = H.voice + + if(hard_to_hear) + speaker_name = "unknown" + + var/changed_voice + + if(istype(src, /mob/living/silicon/ai) && !hard_to_hear) + var/jobname // the mob's "job" + var/mob/living/carbon/human/impersonating //The crewmember being impersonated, if any. + + if (ishuman(speaker)) + var/mob/living/carbon/human/H = speaker + + if((H.wear_id && istype(H.wear_id,/obj/item/weapon/card/id/syndicate)) && (H.wear_mask && istype(H.wear_mask,/obj/item/clothing/mask/gas/voice))) + + changed_voice = 1 + var/mob/living/carbon/human/I = locate(speaker_name) + + if(I) + impersonating = I + jobname = impersonating.get_assignment() + else + jobname = "Unknown" + else + jobname = H.get_assignment() + + else if (iscarbon(speaker)) // Nonhuman carbon mob + jobname = "No id" + else if (isAI(speaker)) + jobname = "AI" + else if (isrobot(speaker)) + jobname = "Cyborg" + else if (istype(speaker, /mob/living/silicon/pai)) + jobname = "Personal AI" + else + jobname = "Unknown" + + if(changed_voice) + if(impersonating) + track = "[speaker_name] ([jobname])" + else + track = "[speaker_name] ([jobname])" + else + track = "[speaker_name] ([jobname])" + + if(istype(src, /mob/dead/observer)) + if(speaker_name != speaker.real_name && !isAI(speaker)) //Announce computer and various stuff that broadcasts doesn't use it's real name but AI's can't pretend to be other mobs. + speaker_name = "[speaker.real_name] ([speaker_name])" + track = "[speaker_name] (follow)" + + var/formatted + if(language) + formatted = language.format_message_radio(message, verb) + else + formatted = "[verb], \"[message]\"" + if(sdisabilities & DEAF || ear_deaf) + if(prob(20)) + src << "You feel your headset vibrate but can hear nothing from it!" + else if(track) + src << "[part_a][track][part_b][formatted]" + else + src << "[part_a][speaker_name][part_b][formatted]" + +/mob/proc/hear_signlang(var/message, var/verb = "gestures", var/datum/language/language, var/mob/speaker = null) + if(!client) + return + + if(say_understands(speaker, language)) + message = "[src] [verb], \"[message]\"" + else + message = "[src] [verb]." + + if(src.status_flags & PASSEMOTES) + for(var/obj/item/weapon/holder/H in src.contents) + H.show_message(message) + for(var/mob/living/M in src.contents) + M.show_message(message) + src.show_message(message) + +/mob/proc/hear_sleep(var/message) + var/heard = "" + if(prob(15)) + var/list/punctuation = list(",", "!", ".", ";", "?") + var/list/messages = text2list(message, " ") + var/R = rand(1, messages.len) + var/heardword = messages[R] + if(copytext(heardword,1, 1) in punctuation) + heardword = copytext(heardword,2) + if(copytext(heardword,-1) in punctuation) + heardword = copytext(heardword,1,lentext(heardword)) + heard = "...You hear something about...[heardword]" + + else + heard = "...You almost hear someone talking..." + + src << heard diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm index a31c958b2c6..a6c0ce6614d 100644 --- a/code/modules/mob/holder.dm +++ b/code/modules/mob/holder.dm @@ -26,9 +26,9 @@ del(src) -/obj/item/weapon/holder/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/holder/attackby(obj/item/weapon/W as obj, mob/user as mob, params) for(var/mob/M in src.contents) - M.attackby(W,user) + M.attackby(W,user, params) /obj/item/weapon/holder/proc/show_message(var/message, var/m_type) for(var/mob/living/M in contents) diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index c8b38aff840..1f0c56d857e 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -22,8 +22,10 @@ //Puts the item into your l_hand if possible and calls all necessary triggers/updates. returns 1 on success. /mob/proc/put_in_l_hand(var/obj/item/W) - if(lying) return 0 - if(!istype(W)) return 0 + if(lying && !(W.flags & ABSTRACT)) + return 0 + if(!istype(W)) + return 0 if(!l_hand) W.loc = src //TODO: move to equipped? l_hand = W @@ -38,8 +40,10 @@ //Puts the item into your r_hand if possible and calls all necessary triggers/updates. returns 1 on success. /mob/proc/put_in_r_hand(var/obj/item/W) - if(lying) return 0 - if(!istype(W)) return 0 + if(lying && !(W.flags & ABSTRACT)) + return 0 + if(!istype(W)) + return 0 if(!r_hand) W.loc = src r_hand = W @@ -76,98 +80,51 @@ return drop_item() return 0 - -/mob/proc/drop_from_inventory(var/obj/item/W) - if(W) - if(client) client.screen -= W - u_equip(W) - if(!W) return 1 // self destroying objects (tk, grabs) - W.layer = initial(W.layer) - W.loc = loc - - var/turf/T = get_turf(loc) - if(isturf(T)) - T.Entered(W) - - W.dropped(src) - update_icons() - return 1 - return 0 - - //Drops the item in our left hand -/mob/proc/drop_l_hand(var/atom/Target) - if(l_hand) - if(client) client.screen -= l_hand - l_hand.layer = initial(l_hand.layer) - - if(Target) l_hand.loc = Target.loc - else l_hand.loc = loc - - var/turf/T = get_turf(loc) - if(isturf(T)) - T.Entered(l_hand) - - l_hand.dropped(src) - l_hand = null - update_inv_l_hand() - return 1 - return 0 +/mob/proc/drop_l_hand() + return unEquip(l_hand) //All needed checks are in unEquip //Drops the item in our right hand -/mob/proc/drop_r_hand(var/atom/Target) - if(r_hand) - if(client) client.screen -= r_hand - r_hand.layer = initial(r_hand.layer) - - if(Target) r_hand.loc = Target.loc - else r_hand.loc = loc - - var/turf/T = get_turf(Target) - if(istype(T)) - T.Entered(r_hand) - - r_hand.dropped(src) - r_hand = null - update_inv_r_hand() - return 1 - return 0 +/mob/proc/drop_r_hand() + return unEquip(r_hand) //Why was this not calling unEquip in the first place jesus fuck. //Drops the item in our active hand. -/mob/proc/drop_item(var/atom/Target) - if(hand) return drop_l_hand(Target) - else return drop_r_hand(Target) +/mob/proc/drop_item() //THIS. DOES. NOT. NEED. AN. ARGUMENT. + if(hand) + return drop_l_hand() + else + return drop_r_hand() -//TODO: phase out this proc -/mob/proc/before_take_item(var/obj/item/W) //TODO: what is this? - W.loc = null - W.layer = initial(W.layer) - u_equip(W) - update_icons() - return +//Here lie unEquip and before_item_take, already forgotten and not missed. -/mob/proc/u_equip(W as obj) - if (W == r_hand) +/mob/proc/unEquip(obj/item/I, force) //Force overrides NODROP for things like wizarditis and admin undress. + if(!I) //If there's nothing to drop, the drop is automatically succesfull. If(unEquip) should generally be used to check for NODROP. + return 1 + + if((I.flags & NODROP) && !force) + return 0 + + if(I == r_hand) r_hand = null - update_inv_r_hand(0) - else if (W == l_hand) + update_inv_r_hand() + else if(I == l_hand) l_hand = null - update_inv_l_hand(0) - else if (W == back) - back = null - update_inv_back(0) - else if (W == wear_mask) - wear_mask = null - update_inv_wear_mask(0) - return + update_inv_l_hand() + + if(I) + if(client) + client.screen -= I + I.loc = loc + I.dropped(src) + if(I) + I.layer = initial(I.layer) + + return 1 //Attemps to remove an object on a mob. Will not move it to another area or such, just removes from the mob. /mob/proc/remove_from_mob(var/obj/O) - src.u_equip(O) - if (src.client) - src.client.screen -= O - O.layer = initial(O.layer) + unEquip(O) O.screen_loc = null return 1 diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm index 0a043db41ef..177d189cb2c 100644 --- a/code/modules/mob/language.dm +++ b/code/modules/mob/language.dm @@ -1,3 +1,5 @@ +#define SCRAMBLE_CACHE_LEN 20 + /* Datum based languages. Easily editable and modular. */ @@ -5,13 +7,112 @@ /datum/language var/name = "an unknown language" // Fluff name of language if any. var/desc = "A language." // Short description for 'Check Languages'. - var/speech_verb = "says" // 'says', 'hisses'. - var/ask_verb = "asks" // Used when sentence ends in a ? + var/speech_verb = "says" // 'says', 'hisses', 'farts'. + var/ask_verb = "asks" // Used when sentence ends in a ? var/exclaim_verb = "exclaims" // Used when sentence ends in a ! - var/colour = "say_quote" // CSS style to use for strings in this language. + var/whisper_verb // Optional. When not specified speech_verb + quietly/softly is used instead. + var/signlang_verb = list() // list of emotes that might be displayed if this language has NONVERBAL or SIGNLANG flags + var/colour = "body" // CSS style to use for strings in this language. var/key = "x" // Character used to speak in language eg. :o for Unathi. var/flags = 0 // Various language flags. var/native // If set, non-native speakers will have trouble speaking. + var/list/syllables // Used when scrambling text for a non-speaker. + var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string. + var/follow = 0 // Applies to HIVEMIND languages - should a follow link be included for dead mobs? + +/datum/language/proc/get_random_name(var/gender, name_count=2, syllable_count=4) + if(!syllables || !syllables.len) + if(gender==FEMALE) + return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names)) + else + return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names)) + + var/full_name = "" + var/new_name = "" + + for(var/i = 0;i0;x--) + new_name += pick(syllables) + full_name += " [capitalize(lowertext(new_name))]" + + return "[trim(full_name)]" + +/datum/language + var/list/scramble_cache = list() + +/datum/language/proc/scramble(var/input) + + if(!syllables || !syllables.len) + return stars(input) + + // If the input is cached already, move it to the end of the cache and return it + if(input in scramble_cache) + var/n = scramble_cache[input] + scramble_cache -= input + scramble_cache[input] = n + return n + + var/input_size = length(input) + var/scrambled_text = "" + var/capitalize = 1 + + while(length(scrambled_text) < input_size) + var/next = pick(syllables) + if(capitalize) + next = capitalize(next) + capitalize = 0 + scrambled_text += next + var/chance = rand(100) + if(chance <= 5) + scrambled_text += ". " + capitalize = 1 + else if(chance > 5 && chance <= space_chance) + scrambled_text += " " + + scrambled_text = trim(scrambled_text) + var/ending = copytext(scrambled_text, length(scrambled_text)) + if(ending == ".") + scrambled_text = copytext(scrambled_text,1,length(scrambled_text)-1) + var/input_ending = copytext(input, input_size) + if(input_ending in list("!","?",".")) + scrambled_text += input_ending + + // Add it to cache, cutting old entries if the list is too long + scramble_cache[input] = scrambled_text + if(scramble_cache.len > SCRAMBLE_CACHE_LEN) + scramble_cache.Cut(1, scramble_cache.len-SCRAMBLE_CACHE_LEN-1) + + + return scrambled_text + +/datum/language/proc/format_message(message, verb) + return "[verb], \"[capitalize(message)]\"" + +/datum/language/proc/format_message_radio(message, verb) + return "[verb], \"[capitalize(message)]\"" + +/datum/language/proc/get_talkinto_msg_range(message) + // if you yell, you'll be heard from two tiles over instead of one + return (copytext(message, length(message)) == "!") ? 2 : 1 + +/datum/language/proc/broadcast(var/mob/living/speaker,var/message,var/speaker_mask) + log_say("[key_name(speaker)] : ([name]) [message]") + + if(!speaker_mask) speaker_mask = speaker.name + var/msg = "[name], [speaker_mask] [format_message(message, get_spoken_verb(message))]" + + for(var/mob/player in player_list) + if(istype(player,/mob/dead) && follow) + var/msg_dead = "[name], [speaker_mask] (follow) [format_message(message, get_spoken_verb(message))]" + player << msg_dead + continue + + else if(istype(player,/mob/dead) || ((src in player.languages) && check_special_condition(player))) + player << msg + +/datum/language/proc/check_special_condition(var/mob/other) + return 1 /datum/language/proc/get_spoken_verb(var/msg_end) switch(msg_end) @@ -19,8 +120,25 @@ return exclaim_verb if("?") return ask_verb - return speech_verb - + return speech_verb + +// Noise "language", for audible emotes. +/datum/language/noise + name = "Noise" + desc = "Noises" + key = "" + flags = RESTRICTED|NONGLOBAL|INNATE|NO_TALK_MSG + +/datum/language/noise/format_message(message, verb) + return "[message]" + +/datum/language/noise/format_message_radio(message, verb) + return "[message]" + +/datum/language/noise/get_talkinto_msg_range(message) + // if you make a loud noise (screams etc), you'll be heard from 4 tiles over instead of two + return (copytext(message, length(message)) == "!") ? 4 : 2 + /datum/language/unathi name = "Sinta'unathi" desc = "The common language of Moghes, composed of sibilant hisses and rattles. Spoken natively by Unathi." @@ -29,17 +147,38 @@ exclaim_verb = "roars" colour = "soghun" key = "o" - flags = WHITELISTED + flags = RESTRICTED + syllables = list("ss","ss","ss","ss","skak","seeki","resh","las","esi","kor","sh") + +/datum/language/unathi/get_random_name() + + var/new_name = ..() + while(findtextEx(new_name,"sss",1,null)) + new_name = replacetext(new_name, "sss", "ss") + return capitalize(new_name) /datum/language/tajaran name = "Siik'tajr" - desc = "An expressive language that combines yowls and chirps with posture, tail and ears. Native to the Tajaran." + desc = "The traditionally employed tongue of Ahdomai, composed of expressive yowls and chirps. Native to the Tajaran." speech_verb = "mrowls" ask_verb = "mrowls" exclaim_verb = "yowls" colour = "tajaran" key = "j" - flags = WHITELISTED + flags = RESTRICTED + syllables = list("rr","rr","tajr","kir","raj","kii","mir","kra","ahk","nal","vah","khaz","jri","ran","darr", \ + "mi","jri","dynh","manq","rhe","zar","rrhaz","kal","chur","eech","thaa","dra","jurl","mah","sanu","dra","ii'r", \ + "ka","aasi","far","wa","baq","ara","qara","zir","sam","mak","hrar","nja","rir","khan","jun","dar","rik","kah", \ + "hal","ket","jurl","mah","tul","cresh","azu","ragh") + +/datum/language/tajaran/get_random_name(var/gender) + + var/new_name = ..(gender,1) + if(prob(80)) + new_name += " [pick(list("Hadii","Kaytam","Zhan-Khazan","Hharar","Njarir'Akhan"))]" + else + new_name += ..(gender,1) + return new_name /datum/language/skrell name = "Skrellian" @@ -49,7 +188,8 @@ exclaim_verb = "warbles" colour = "skrell" key = "k" - flags = WHITELISTED + flags = RESTRICTED + syllables = list("qr","qrr","xuq","qil","quum","xuqm","vol","xrim","zaoo","qu-uu","qix","qoo","zix","*","!") /datum/language/vox name = "Vox-pidgin" @@ -59,7 +199,12 @@ exclaim_verb = "SHRIEKS" colour = "vox" key = "v" - flags = RESTRICTED + flags = RESTRICTED | WHITELISTED + syllables = list("ti","ti","ti","hi","hi","ki","ki","ki","ki","ya","ta","ha","ka","ya","chi","cha","kah", \ + "SKRE","AHK","EHK","RAWK","KRA","AAA","EEE","KI","II","KRI","KA") + +/datum/language/vox/get_random_name() + return ..(FEMALE,1,6) /datum/language/diona name = "Rootspeak" @@ -67,79 +212,266 @@ speech_verb = "creaks and rustles" ask_verb = "creaks" exclaim_verb = "rustles" - colour = "soghun" + colour = "diona" key = "q" flags = RESTRICTED + syllables = list("hs","zt","kr","st","sh") + +/datum/language/diona/get_random_name() + var/new_name = "[pick(list("To Sleep Beneath","Wind Over","Embrace of","Dreams of","Witnessing","To Walk Beneath","Approaching the"))]" + new_name += " [pick(list("the Void","the Sky","Encroaching Night","Planetsong","Starsong","the Wandering Star","the Empty Day","Daybreak","Nightfall","the Rain"))]" + return new_name + +/datum/language/trinary + name = "Trinary" + desc = "A modification of binary to allow fuzzy logic. 0 is no, 1 is maybe, 2 is yes. Credited with giving Machine People the ability to think creatively." + speech_verb = "states" + ask_verb = "queries" + exclaim_verb = "exclaims" + colour = "trinary" + key = "5" + flags = RESTRICTED | WHITELISTED + syllables = list("02011","01222","10100","10210","21012","02011","21200","1002","2001","0002","0012","0012","000","120","121","201","220","10","11","0") /datum/language/kidan name = "Chittin" - desc = "The noise made by rubbing it's antennae together is actually a complex form of communication for Kidan." - speech_verb = "rubs its antenna together" - ask_verb = "rubs its antenna together" - exclaim_verb = "rubs its antenna together" - colour = "tajaran" + desc = "The noise made by rubbing its antennae together is actually a complex form of communication for Kidan." + speech_verb = "rubs its antennae together" + ask_verb = "rubs its antennae together" + exclaim_verb = "rubs its antennae together" + colour = "kidan" key = "4" - flags = RESTRICTED + flags = RESTRICTED | WHITELISTED + syllables = list("click","clack") /datum/language/slime name = "Bubblish" - desc = "Languages of slimes, a mixture of bubbling noises and pops. Almost impossible to speak without mechanical aid for non slime people." + desc = "The language of slimes. It's a mixture of bubbling noises and pops. Very difficult to speak without mechanical aid for humans." speech_verb = "bubbles and pops" ask_verb = "bubbles and pops" exclaim_verb = "bubbles and pops" - colour = "skrell" + colour = "slime" key = "f" + flags = RESTRICTED | WHITELISTED + syllables = list("blob","plop","pop","bop","boop") + +/datum/language/common + name = "Galactic Common" + desc = "The common galactic tongue." + speech_verb = "says" + whisper_verb = "whispers" + key = "0" flags = RESTRICTED + syllables = list("blah","blah","blah","bleh","meh","neh","nah","wah") + +//TODO flag certain languages to use the mob-type specific say_quote and then get rid of these. +/datum/language/common/get_spoken_verb(var/msg_end) + switch(msg_end) + if("!") + return pick("exclaims","shouts","yells") //TODO: make the basic proc handle lists of verbs. + if("?") + return ask_verb + return speech_verb /datum/language/human name = "Sol Common" desc = "A bastardized hybrid of informal English and elements of Mandarin Chinese; the common language of the Sol system." + speech_verb = "says" + whisper_verb = "whispers" + colour = "solcom" key = "1" flags = RESTRICTED + syllables = list("tao","shi","tzu","yi","com","be","is","i","op","vi","ed","lec","mo","cle","te","dis","e") -/datum/language/trinary - name = "Trinary" - desc = "A modification of binary to allow fuzzy logic. 0 is no, 1 maybe, 2 yes. Credited with giving Machine People the ability to think creatively." - key = "5" - flags = RESTRICTED - +/datum/language/human/get_spoken_verb(var/msg_end) + switch(msg_end) + if("!") + return pick("exclaims","shouts","yells") //TODO: make the basic proc handle lists of verbs. + if("?") + return ask_verb + return speech_verb // Galactic common languages (systemwide accepted standards). /datum/language/trader name = "Tradeband" desc = "Maintained by the various trading cartels in major systems, this elegant, structured language is used for bartering and bargaining." speech_verb = "enunciates" + colour = "say_quote" key = "2" + space_chance = 100 + syllables = list("lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit", + "sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore", "et", "dolore", + "magna", "aliqua", "ut", "enim", "ad", "minim", "veniam", "quis", "nostrud", + "exercitation", "ullamco", "laboris", "nisi", "ut", "aliquip", "ex", "ea", "commodo", + "consequat", "duis", "aute", "irure", "dolor", "in", "reprehenderit", "in", + "voluptate", "velit", "esse", "cillum", "dolore", "eu", "fugiat", "nulla", + "pariatur", "excepteur", "sint", "occaecat", "cupidatat", "non", "proident", "sunt", + "in", "culpa", "qui", "officia", "deserunt", "mollit", "anim", "id", "est", "laborum") /datum/language/gutter name = "Gutter" desc = "Much like Standard, this crude pidgin tongue descended from numerous languages and serves as Tradeband for criminal elements." speech_verb = "growls" + colour = "rough" key = "3" + syllables = list ("gra","ba","ba","breh","bra","rah","dur","ra","ro","gro","go","ber","bar","geh","heh", "gra") + +/datum/language/clown + name = "Clownish" + desc = "The language of clown planet. Mother tongue of clowns throughout the Galaxy." + speech_verb = "honks" + ask_verb = "honks" + exclaim_verb = "honks" + colour = "clown" + key = "0" + syllables = list ("honk","squeak","bonk","toot","narf","zub","wee","wub","norf") + +/datum/language/xenocommon + name = "Xenomorph" + colour = "alien" + desc = "The common tongue of the xenomorphs." + speech_verb = "hisses" + ask_verb = "hisses" + exclaim_verb = "hisses" + key = "6" + flags = RESTRICTED + syllables = list("sss","sSs","SSS") + +/datum/language/xenos + name = "Hivemind" + desc = "Xenomorphs have the strange ability to commune over a psychic hivemind." + speech_verb = "hisses" + ask_verb = "hisses" + exclaim_verb = "hisses" + colour = "alien" + key = "a" + flags = RESTRICTED | HIVEMIND + follow = 1 + +/datum/language/ling + name = "Changeling" + desc = "Although they are normally wary and suspicious of each other, changelings can commune over a distance." + speech_verb = "says" + colour = "changeling" + key = "g" + flags = RESTRICTED | HIVEMIND + +/datum/language/ling/broadcast(var/mob/living/speaker,var/message,var/speaker_mask) + + if(speaker.mind && speaker.mind.changeling) + ..(speaker,message,speaker.mind.changeling.changelingID) + else + ..(speaker,message) + +/datum/language/corticalborer + name = "Cortical Link" + desc = "Cortical borers possess a strange link between their tiny minds." + speech_verb = "sings" + ask_verb = "sings" + exclaim_verb = "sings" + colour = "alien" + key = "x" + flags = RESTRICTED | HIVEMIND + +/datum/language/corticalborer/broadcast(var/mob/living/speaker,var/message,var/speaker_mask) + + var/mob/living/simple_animal/borer/B + + if(istype(speaker,/mob/living/carbon)) + var/mob/living/carbon/M = speaker + B = M.has_brain_worms() + else if(istype(speaker,/mob/living/simple_animal/borer)) + B = speaker + + if(B) + speaker_mask = B.truename + ..(speaker,message,speaker_mask) + +/datum/language/binary + name = "Robot Talk" + desc = "Most human stations support free-use communications protocols and routing hubs for synthetic use." + colour = "say_quote" + speech_verb = "states" + ask_verb = "queries" + exclaim_verb = "declares" + key = "b" + flags = RESTRICTED | HIVEMIND + follow = 1 + var/drone_only + +/datum/language/binary/broadcast(var/mob/living/speaker,var/message,var/speaker_mask) + + if(!speaker.binarycheck()) + return + + if (!message) + return + + var/message_start = "[name], [speaker.name]" + var/message_body = "[speaker.say_quote(message)], \"[message]\"" + + for (var/mob/M in dead_mob_list) + if(!istype(M,/mob/new_player) && !istype(M,/mob/living/carbon/brain)) + var/message_start_dead = "[name], [speaker.name] (follow)" + M.show_message("[message_start_dead] [message_body]", 2) + + for (var/mob/living/S in living_mob_list) + + if(drone_only && !istype(S,/mob/living/silicon/robot/drone)) + continue + else if(istype(S , /mob/living/silicon/ai)) + message_start = "[name], [speaker.name]" + else if (!S.binarycheck()) + continue + + S.show_message("[message_start] [message_body]", 2) + + var/list/listening = hearers(1, src) + listening -= src + + for (var/mob/living/M in listening) + if(istype(M, /mob/living/silicon) || M.binarycheck()) + continue + M.show_message("synthesised voice beeps, \"beep beep beep\"",2) + + //robot binary xmitter component power usage + if (isrobot(speaker)) + var/mob/living/silicon/robot/R = speaker + var/datum/robot_component/C = R.components["comms"] + R.use_power(C.energy_consumption) + +/datum/language/binary/drone + name = "Drone Talk" + desc = "A heavily encoded damage control coordination stream." + speech_verb = "transmits" + ask_verb = "transmits" + exclaim_verb = "transmits" + colour = "say_quote" + key = "d" + flags = RESTRICTED | HIVEMIND + drone_only = 1 + follow = 1 // Language handling. /mob/proc/add_language(var/language) - for(var/datum/language/L in languages) - if(L && L.name == language) - return 0 - var/datum/language/new_language = all_languages[language] - if(!istype(new_language,/datum/language)) + if(!istype(new_language) || new_language in languages) return 0 - languages += new_language + languages |= new_language return 1 /mob/proc/remove_language(var/rem_language) + var/datum/language/L = all_languages[rem_language] + . = (L in languages) + languages.Remove(L) - for(var/datum/language/L in languages) - if(L && L.name == rem_language) - languages -= L - return 1 +// Can we speak this language, as opposed to just understanding it? +/mob/proc/can_speak(datum/language/speaking) - return 0 + return (universal_speak || (speaking && speaking.flags & INNATE) || speaking in src.languages) //TBD /mob/verb/check_languages() @@ -150,7 +482,10 @@ var/dat = "Known Languages

" for(var/datum/language/L in languages) - dat += "[L.name] (:[L.key])
[L.desc]

" + if(!(L.flags & NONGLOBAL)) + dat += "[L.name] (:[L.key])
[L.desc]

" src << browse(dat, "window=checklanguage") - return \ No newline at end of file + return + +#undef SCRAMBLE_CACHE_LEN diff --git a/code/modules/mob/living/carbon/_defines.dm b/code/modules/mob/living/carbon/_defines.dm index aa8fa28c131..2abbbf91cbc 100644 --- a/code/modules/mob/living/carbon/_defines.dm +++ b/code/modules/mob/living/carbon/_defines.dm @@ -1,6 +1,6 @@ //NOTE: Breathing happens once per FOUR TICKS, unless the last breath fails. In which case it happens once per ONE TICK! So oxyloss healing is done once per 4 ticks while oxyloss damage is applied once per tick! #define HUMAN_MAX_OXYLOSS 3 //Defines how much oxyloss humans can get per tick. A tile with no air at all (such as space) applies this value, otherwise it's a percentage of it. -#define HUMAN_CRIT_MAX_OXYLOSS ( (last_tick_duration) /5) //The amount of damage you'll get when in critical condition. We want this to be a 5 minute deal = 300s. There are 100HP to get through, so (1/3)*last_tick_duration per second. Breaths however only happen every 4 ticks. +#define HUMAN_CRIT_MAX_OXYLOSS ( (tickerProcess.getLastTickerTimeDuration()) / 3) //The amount of damage you'll get when in critical condition. We want this to be a 5 minute deal = 300s. There are 100HP to get through, so (1/3)*last_tick_duration per second. Breaths however only happen every 4 ticks. #define HEAT_DAMAGE_LEVEL_1 2 //Amount of damage applied when your body temperature just passes the 360.15k safety point #define HEAT_DAMAGE_LEVEL_2 3 //Amount of damage applied when your body temperature passes the 400K point diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index 7e6bb5ea7da..04004b1ac93 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -125,7 +125,7 @@ /mob/living/carbon/alien/proc/handle_mutations_and_radiation() if(getFireLoss()) - if((M_RESIST_HEAT in mutations) || prob(5)) + if((RESIST_HEAT in mutations) || prob(5)) adjustFireLoss(-1) // Aliens love radiation nom nom nom diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm index c11272e06ed..7a607c72e77 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm @@ -1,8 +1,8 @@ /mob/living/carbon/alien/humanoid/hunter name = "alien hunter" caste = "h" - maxHealth = 150 - health = 150 + maxHealth = 125 + health = 125 storedPlasma = 100 max_plasma = 150 icon_state = "alienh_s" @@ -88,12 +88,14 @@ update_icons() /mob/living/carbon/alien/humanoid/hunter/throw_impact(A) - var/msg = "" + + if(!leaping) + return ..() if(A) if(istype(A, /mob/living)) var/mob/living/L = A - msg = "[src] pounces on [A]!" + L.visible_message("[src] pounces on [L]!", "[src] pounces on you!") L.Weaken(5) sleep(2)//Runtime prevention (infinite bump() calls on hulks) step_towards(src,L) @@ -103,13 +105,12 @@ spawn(pounce_cooldown_time) //3s by default pounce_cooldown = !pounce_cooldown else - msg = "[src] smashes into [A]!" + visible_message("[src] smashes into [A]!", "[src] smashes into [A]!") weakened = 2 if(leaping) leaping = 0 update_canmove() - visible_message(msg) /mob/living/carbon/alien/humanoid/float(on) @@ -157,7 +158,5 @@ src.throwing = 0 - if(isobj(src)) - src.throw_impact(get_turf(src)) return 1 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm index a06482242c2..5870ca062d8 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm @@ -1,8 +1,8 @@ /mob/living/carbon/alien/humanoid/sentinel name = "alien sentinel" caste = "s" - maxHealth = 125 - health = 125 + maxHealth = 150 + health = 150 storedPlasma = 100 max_plasma = 250 icon_state = "aliens_s" diff --git a/code/modules/mob/living/carbon/alien/humanoid/emote.dm b/code/modules/mob/living/carbon/alien/humanoid/emote.dm index 71dc56ef402..d0f4cf86aad 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/emote.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/emote.dm @@ -8,7 +8,7 @@ if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_' act = copytext(act,1,length(act)) - var/muzzled = istype(src.wear_mask, /obj/item/clothing/mask/muzzle) + var/muzzled = is_muzzled() switch(act) if ("me") diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index 0eb6fe764ee..c3e0022ff00 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -21,6 +21,8 @@ if(name == "alien") name = text("alien ([rand(1, 1000)])") real_name = name + add_language("Xenomorph") + add_language("Hivemind") ..() //This is fine, works the same as a human @@ -63,20 +65,20 @@ return (tally + move_delay_add + config.alien_delay) /mob/living/carbon/alien/humanoid/Process_Spacemove(var/check_drift = 0) - return 1 + if(..()) + return 1 + + return 0 ///mob/living/carbon/alien/humanoid/bullet_act(var/obj/item/projectile/Proj) taken care of in living /mob/living/carbon/alien/humanoid/emp_act(severity) - if(wear_suit) wear_suit.emp_act(severity) - if(head) head.emp_act(severity) if(r_store) r_store.emp_act(severity) if(l_store) l_store.emp_act(severity) ..() /mob/living/carbon/alien/humanoid/ex_act(severity) - if(!blinded) - flick("flash", flash) + ..() var/shielded = 0 @@ -84,7 +86,6 @@ var/f_loss = null switch (severity) if (1.0) - b_loss += 500 gib() return @@ -120,8 +121,7 @@ if(shielded) damage /= 4 - - show_message("\red The blob attacks!") + show_message("The blob attacks!") adjustFireLoss(damage) return @@ -136,6 +136,35 @@ updatehealth() return +/mob/living/carbon/alien/humanoid/attack_paw(mob/living/carbon/monkey/M as mob) + if(!ismonkey(M)) return//Fix for aliens receiving double messages when attacking other aliens. + + if (!ticker) + M << "You cannot attack people before the game has started." + return + + if (istype(loc, /turf) && istype(loc.loc, /area/start)) + M << "No attacking people at spawn, you jackass." + return + ..() + + switch(M.a_intent) + + if ("help") + help_shake_act(M) + else + M.do_attack_animation(src) + if (istype(src.wear_mask, /obj/item/clothing/mask/muzzle)) + return + playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) + visible_message("[M.name] bites [src]!", \ + "[M.name] bites [src]!") + if (health > -100) + adjustBruteLoss(rand(1, 3)) + updatehealth() + return + + /mob/living/carbon/alien/humanoid/attack_slime(mob/living/carbon/slime/M as mob) if (!ticker) M << "You cannot attack people before the game has started." @@ -143,12 +172,11 @@ if(M.Victim) return // can't attack while eating! - if (health > -100) - - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red The [M.name] glomps []!", src), 1) + if (stat > -100) + M.do_attack_animation(src) + visible_message("The [M.name] glomps [src]!", \ + "The [M.name] glomps [src]!") var/damage = rand(1, 3) if(M.is_adult) @@ -175,9 +203,8 @@ if(M.powerlevel < 0) M.powerlevel = 0 - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red The [M.name] has shocked []!", src), 1) + visible_message("The [M.name] has shocked [src]!", \ + "The [M.name] has shocked [src]!") Weaken(power) if (stuttering < power) @@ -196,6 +223,19 @@ return +/mob/living/carbon/alien/humanoid/attack_animal(mob/living/simple_animal/M as mob) + if(M.melee_damage_upper == 0) + M.emote("[M.friendly] [src]") + else + M.do_attack_animation(src) + if(M.attack_sound) + playsound(loc, M.attack_sound, 50, 1, 1) + visible_message("[M] [M.attacktext] [src]!", \ + "[M] [M.attacktext] [src]!") + var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) + adjustBruteLoss(damage) + updatehealth() + /mob/living/carbon/alien/humanoid/attack_hand(mob/living/carbon/human/M as mob) if (!ticker) M << "You cannot attack people before the game has started." @@ -205,95 +245,135 @@ M << "No attacking people at spawn, you jackass." return + if(..()) //to allow surgery to return properly. + return + + switch(M.a_intent) + + if ("help") + help_shake_act(M) + + if ("grab") + if (M == src || anchored) + return + var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src) + + M.put_in_active_hand(G) + + G.synch() + + LAssailant = M + + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + visible_message("[M] has grabbed [src] passively!") + + if ("harm") + M.do_attack_animation(src) + var/damage = rand(1, 9) + if (prob(90)) + if (HULK in M.mutations)//HULK SMASH + damage += 14 + spawn(0) + Paralyse(1) + step_away(src,M,15) + sleep(3) + step_away(src,M,15) + playsound(loc, "punch", 25, 1, -1) + visible_message("[M] has punched [src]!", \ + "[M] has punched [src]!") + if ((stat != DEAD) && (damage > 9||prob(5)))//Regular humans have a very small chance of weakening an alien. + Paralyse(2) + visible_message("[M] has weakened [src]!", \ + "[M] has weakened [src]!", \ + "You hear someone fall.") + adjustBruteLoss(damage) + updatehealth() + else + playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + visible_message("[M] has attempted to punch [src]!") + + if ("disarm") + if (!lying) + if (prob(5))//Very small chance to push an alien down. + Paralyse(2) + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + visible_message("[M] has pushed down [src]!", \ + "[M] has pushed down [src]!") + else + if (prob(50)) + drop_item() + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + visible_message("[M] has disarmed [src]!", \ + "[M] has disarmed [src]!") + else + playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + visible_message("[M] has attempted to disarm [src]!") + return + +/*Code for aliens attacking aliens. Because aliens act on a hivemind, I don't see them as very aggressive with each other. +As such, they can either help or harm other aliens. Help works like the human help command while harm is a simple nibble. +In all, this is a lot like the monkey code. /N +*/ + +/mob/living/carbon/alien/humanoid/attack_alien(mob/living/carbon/alien/humanoid/M as mob) + if (!ticker) + M << "You cannot attack people before the game has started." + return + + if (istype(loc, /turf) && istype(loc.loc, /area/start)) + M << "No attacking people at spawn, you jackass." + return + ..() switch(M.a_intent) if ("help") + sleeping = max(0,sleeping-5) + resting = 0 + AdjustParalysis(-3) + AdjustStunned(-3) + AdjustWeakened(-3) + visible_message("[M.name] nuzzles [src] trying to wake it up!") + + else if (health > 0) - help_shake_act(M) - else - if (M.health >= -75.0) - if (((M.head && M.head.flags & 4) || ((M.wear_mask && !( M.wear_mask.flags & 32 )) || ((head && head.flags & 4) || (wear_mask && !( wear_mask.flags & 32 )))))) - M << "\blue Remove that mask!" - return - var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human( ) - O.source = M - O.target = src - O.s_loc = M.loc - O.t_loc = loc - O.place = "CPR" - requests += O - spawn( 0 ) - O.process() - return + M.do_attack_animation(src) + playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) + var/damage = rand(1, 3) + visible_message("[M.name] bites [src]!!", \ + "[M.name] bites [src]!!") - if ("grab") - if (M == src || anchored) - return - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src) - - M.put_in_active_hand(G) - - grabbed_by += G - G.synch() - - LAssailant = M - - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has grabbed [] passively!", M, src), 1) - - if ("harm") - var/damage = rand(1, 9) - if (prob(90)) - if (M_HULK in M.mutations)//M_HULK SMASH - damage += 14 - spawn(0) - Paralyse(1) - step_away(src,M,15) - sleep(3) - step_away(src,M,15) - playsound(loc, "punch", 25, 1, -1) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has punched []!", M, src), 1) - if (damage > 9||prob(5))//Regular humans have a very small chance of weakening an alien. - Paralyse(2) - for(var/mob/O in viewers(M, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has weakened []!", M, src), 1, "\red You hear someone fall.", 2) adjustBruteLoss(damage) updatehealth() else - playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has attempted to punch []!", M, src), 1) - - if ("disarm") - if (!lying) - if (prob(5))//Very small chance to push an alien down. - Paralyse(2) - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has pushed down []!", M, src), 1) - else - if (prob(50)) - drop_item() - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has disarmed []!", M, src), 1) - else - playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has attempted to disarm []!", M, src), 1) + M << "[name] is too injured for that." return + +/mob/living/carbon/alien/humanoid/attack_larva(mob/living/carbon/alien/larva/L as mob) + + switch(L.a_intent) + if("help") + visible_message("[L] rubs its head against [src].") + + + else + if (health > 0) + L.do_attack_animation(src) + playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) + var/damage = rand(1, 3) + visible_message("[L.name] bites [src]!!", \ + "[L.name] bites [src]!!") + + adjustBruteLoss(damage) + updatehealth() + else + L << "[name] is too injured for that." + return + + + /mob/living/carbon/alien/humanoid/restrained() if (handcuffed) return 1 @@ -322,4 +402,4 @@ /mob/living/carbon/alien/humanoid/canBeHandcuffed() - return 1 + return 1 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/alien/humanoid/inventory.dm b/code/modules/mob/living/carbon/alien/humanoid/inventory.dm index bf3ca77d02f..d279c11d0a5 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/inventory.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/inventory.dm @@ -1,23 +1,16 @@ //unequip -/mob/living/carbon/alien/humanoid/u_equip(obj/item/W as obj) - if (W == wear_suit) - wear_suit = null - update_inv_wear_suit(0,0) - else if (W == head) - head = null - update_inv_head(0,0) - else if (W == r_store) +/mob/living/carbon/alien/humanoid/unEquip(obj/item/I as obj) + . = ..() + if(!. || !I) + return + + if(I == r_store) r_store = null - update_inv_pockets(0) - else if (W == l_store) + update_inv_pockets() + + else if(I == l_store) l_store = null - update_inv_pockets(0) - else if (W == r_hand) - r_hand = null - update_inv_r_hand(0) - else if (W == l_hand) - l_hand = null - update_inv_l_hand(0) + update_inv_pockets() /mob/living/carbon/alien/humanoid/attack_ui(slot_id) var/obj/item/W = get_active_hand() @@ -31,7 +24,7 @@ return if(W.w_class > 3) return - u_equip(W) + unEquip(W) l_store = W update_inv_pockets() if(slot_r_store) @@ -39,7 +32,7 @@ return if(W.w_class > 3) return - u_equip(W) + unEquip(W) r_store = W update_inv_pockets() else diff --git a/code/modules/mob/living/carbon/alien/humanoid/life.dm b/code/modules/mob/living/carbon/alien/humanoid/life.dm index e59f50a5e5c..22f9bec9e0c 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/life.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/life.dm @@ -187,7 +187,7 @@ /mob/living/carbon/alien/humanoid/proc/handle_regular_hud_updates() - if (stat == 2 || (M_XRAY in mutations)) + if (stat == 2 || (XRAY in mutations)) sight |= SEE_TURFS sight |= SEE_MOBS sight |= SEE_OBJS diff --git a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm index d85d377ae00..6990eaa9223 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm @@ -104,7 +104,7 @@ //TODO wear_suit.screen_loc = ui_alien_oclothing if (istype(wear_suit, /obj/item/clothing/suit/straight_jacket)) - drop_from_inventory(handcuffed) + unEquip(handcuffed) drop_r_hand() drop_l_hand() diff --git a/code/modules/mob/living/carbon/alien/larva/emote.dm b/code/modules/mob/living/carbon/alien/larva/emote.dm index 375c5c6b0c9..12ad431f3c3 100644 --- a/code/modules/mob/living/carbon/alien/larva/emote.dm +++ b/code/modules/mob/living/carbon/alien/larva/emote.dm @@ -8,7 +8,7 @@ if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_' act = copytext(act,1,length(act)) - var/muzzled = istype(src.wear_mask, /obj/item/clothing/mask/muzzle) + var/muzzled = is_muzzled() switch(act) if ("me") diff --git a/code/modules/mob/living/carbon/alien/larva/inventory.dm b/code/modules/mob/living/carbon/alien/larva/inventory.dm index 076053b2530..99298e50bbe 100644 --- a/code/modules/mob/living/carbon/alien/larva/inventory.dm +++ b/code/modules/mob/living/carbon/alien/larva/inventory.dm @@ -1,3 +1,3 @@ //can't unequip since it can't equip anything -/mob/living/carbon/alien/larva/u_equip(obj/item/W as obj) +/mob/living/carbon/alien/larva/unEquip(obj/item/W as obj) return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index 5515c951514..ba9f1a30c7c 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -23,6 +23,8 @@ name = "alien larva ([rand(1, 1000)])" real_name = name regenerate_icons() + add_language("Xenomorph") + add_language("Hivemind") ..() //This is fine, works the same as a human @@ -34,7 +36,7 @@ now_pushing = 1 if(ismob(AM)) var/mob/tmob = AM - if(istype(tmob, /mob/living/carbon/human) && (M_FAT in tmob.mutations)) + if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) if(prob(70)) src << "\red You fail to push [tmob]'s fat ass out of the way." now_pushing = 0 @@ -69,14 +71,12 @@ /mob/living/carbon/alien/larva/ex_act(severity) - if(!blinded) - flick("flash", flash) + ..() var/b_loss = null var/f_loss = null switch (severity) if (1.0) - b_loss += 500 gib() return @@ -117,7 +117,7 @@ //paralysis += 1 - show_message("\red The blob attacks you!") + show_message("The blob attacks you!") adjustFireLoss(damage) @@ -140,31 +140,164 @@ updatehealth() return -/mob/living/carbon/alien/larva/attack_hand(mob/living/carbon/human/M as mob) - if(..()) - var/damage = rand(1, 9) - if (prob(90)) - if (M_HULK in M.mutations) - damage += 5 - spawn(0) - Paralyse(1) - step_away(src,M,15) - sleep(3) - step_away(src,M,15) - playsound(loc, "punch", 25, 1, -1) - add_logs(M, src, "attacked") - visible_message("[M] has kicked [src]!", \ - "[M] has kicked [src]!") - if ((stat != DEAD) && (damage > 4.9)) - Paralyse(rand(5,10)) +/mob/living/carbon/alien/larva/attack_animal(mob/living/simple_animal/M as mob) + if(M.melee_damage_upper == 0) + M.emote("[M.friendly] [src]") + else + M.do_attack_animation(src) + if(M.attack_sound) + playsound(loc, M.attack_sound, 50, 1, 1) + visible_message("[M] [M.attacktext] [src]!", \ + "[M] [M.attacktext] [src]!") + var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) + adjustBruteLoss(damage) + add_logs(M, src, "attacked", admin=0) + updatehealth() - adjustBruteLoss(damage) - updatehealth() + +/mob/living/carbon/alien/larva/attack_paw(mob/living/carbon/monkey/M as mob) + if(!(istype(M, /mob/living/carbon/monkey))) return//Fix for aliens receiving double messages when attacking other aliens. + + if (!ticker) + M << "You cannot attack people before the game has started." + return + + if (istype(loc, /turf) && istype(loc.loc, /area/start)) + M << "No attacking people at spawn, you jackass." + return + ..() + + switch(M.a_intent) + + if ("help") + help_shake_act(M) else - playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - visible_message("[M] has attempted to kick [src]!", \ - "[M] has attempted to kick [src]!") + M.do_attack_animation(src) + if (istype(src.wear_mask, /obj/item/clothing/mask/muzzle)) + return + playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) + visible_message("[M.name] bites [src]!", \ + "[M.name] bites [src]!") + if (health > -100) + adjustBruteLoss(rand(1, 3)) + updatehealth() + return + +/mob/living/carbon/alien/larva/attack_slime(mob/living/carbon/slime/M as mob) + if (!ticker) + M << "You cannot attack people before the game has started." + return + + if(M.Victim) + return // can't attack while eating! + + if (stat != DEAD) + M.do_attack_animation(src) + visible_message("The [M.name] glomps [src]!", \ + "The [M.name] glomps [src]!") + var/damage = rand(1, 3) + + if(M.is_adult) + damage = rand(20, 40) + else + damage = rand(5, 35) + + + adjustBruteLoss(damage) + updatehealth() + + return + +/mob/living/carbon/alien/larva/attack_hand(mob/living/carbon/human/M as mob) + if (!ticker) + M << "You cannot attack people before the game has started." + return + + if (istype(loc, /turf) && istype(loc.loc, /area/start)) + M << "No attacking people at spawn, you jackass." + return + + ..() + + switch(M.a_intent) + + if ("help") + help_shake_act(M) + + if ("grab") + if (M == src || anchored) + return + var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src ) + + M.put_in_active_hand(G) + + G.synch() + + LAssailant = M + + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + visible_message("[M] has grabbed [src] passively!") + + else + M.do_attack_animation(src) + var/damage = rand(1, 9) + if (prob(90)) + if (HULK in M.mutations) + damage += 5 + spawn(0) + Paralyse(1) + step_away(src,M,15) + sleep(3) + step_away(src,M,15) + playsound(loc, "punch", 25, 1, -1) + visible_message("[M] has kicked [src]!", \ + "[M] has kicked [src]!") + if ((stat != DEAD) && (damage > 4.9)) + Paralyse(rand(5,10)) + visible_message("[M] has weakened [src]!", \ + "[M] has weakened [src]!", \ + "You hear someone fall.") + adjustBruteLoss(damage) + updatehealth() + else + playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + visible_message("[M] has attempted to kick [src]!", \ + "[M] has attempted to kick [src]!") + return + +/mob/living/carbon/alien/larva/attack_alien(mob/living/carbon/alien/humanoid/M as mob) + if (!ticker) + M << "You cannot attack people before the game has started." + return + + if (istype(loc, /turf) && istype(loc.loc, /area/start)) + M << "No attacking people at spawn, you jackass." + return + + ..() + + switch(M.a_intent) + + if ("help") + sleeping = max(0,sleeping-5) + resting = 0 + AdjustParalysis(-3) + AdjustStunned(-3) + AdjustWeakened(-3) + visible_message("[M.name] nuzzles [src] trying to wake it up!") + + else + if (health > 0) + M.do_attack_animation(src) + playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) + var/damage = 1 + visible_message("[M.name] bites [src]!", \ + "[M.name] bites [src]!") + adjustBruteLoss(damage) + updatehealth() + else + M << "[name] is too injured for that." return /mob/living/carbon/alien/larva/restrained() diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm index 796f0a7cc00..6930ee09dd9 100644 --- a/code/modules/mob/living/carbon/alien/larva/life.dm +++ b/code/modules/mob/living/carbon/alien/larva/life.dm @@ -135,7 +135,7 @@ /mob/living/carbon/alien/larva/proc/handle_regular_hud_updates() - if (stat == 2 || (M_XRAY in mutations)) + if (stat == 2 || (XRAY in mutations)) sight |= SEE_TURFS sight |= SEE_MOBS sight |= SEE_OBJS diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm index e82dda81b61..2a2d6214e71 100644 --- a/code/modules/mob/living/carbon/alien/life.dm +++ b/code/modules/mob/living/carbon/alien/life.dm @@ -1,5 +1,6 @@ /mob/living/carbon/alien/proc/handle_chemicals_in_body() - if(reagents) reagents.metabolize(src) + if(reagents) + reagents.metabolize(src) if (drowsyness) drowsyness-- @@ -101,7 +102,7 @@ breath.toxins -= toxins_used breath.oxygen += toxins_used - if(breath.temperature > (T0C+66) && !(M_RESIST_COLD in mutations)) // Hot air hurts :( + if(breath.temperature > (T0C+66) && !(RESIST_COLD in mutations)) // Hot air hurts :( if(prob(20)) src << "You feel a searing heat in your lungs!" fire_alert = max(fire_alert, 1) diff --git a/code/modules/mob/living/carbon/alien/say.dm b/code/modules/mob/living/carbon/alien/say.dm index 9604a50559d..4aeace5be7b 100644 --- a/code/modules/mob/living/carbon/alien/say.dm +++ b/code/modules/mob/living/carbon/alien/say.dm @@ -1,69 +1,39 @@ /mob/living/carbon/alien/say(var/message) + var/verb = "says" + var/message_range = world.view - if (silent) - return + if(client) + if(client.prefs.muted & MUTE_IC) + src << "\red You cannot speak in IC (Muted)." + return - if (length(message) >= 2) - if (department_radio_keys[copytext(message, 1, 3)] == "alientalk") - message = copytext(message, 3) - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) - if (stat == 2) - return say_dead(message) - else - alien_talk(message) - else - if (copytext(message, 1, 2) != "*" && !stat) - playsound(loc, "hiss", 25, 1, 1)//So aliens can hiss while they hiss yo/N - return ..(message) + message = trim_strip_html_properly(message) + + if(stat == 2) + return say_dead(message) + + if(copytext(message,1,2) == "*") + return emote(copytext(message,2)) + + var/datum/language/speaking = parse_language(message) + if(speaking) + message = copytext(message,2+length(speaking.key)) else + speaking = all_languages["Xenomorph"] -/mob/living/proc/alien_talk(var/message) + var/ending = copytext(message, length(message)) + if (speaking) + // This is broadcast to all mobs with the language, + // irrespective of distance or anything else. + if(speaking.flags & HIVEMIND) + speaking.broadcast(src,trim(message)) + return + //If we've gotten this far, keep going! + verb = speaking.get_spoken_verb(ending) - log_say("[key_name(src)] : [message]") message = trim(message) - if (!message) + if(!message || stat) return - var/message_a = say_quote(message) - var/rendered = "Hivemind, [name] [message_a]" - for (var/mob/living/S in player_list) - if(!S.stat) - if(S.alien_talk_understand) - if(S.alien_talk_understand == alien_talk_understand) - S.show_message(rendered, 2) - else if (S.hivecheck()) - S.show_message(rendered, 2) - - var/list/listening = hearers(1, src) - listening -= src - listening += src - - var/list/heard = list() - for (var/mob/M in listening) - if(!istype(M, /mob/living/carbon/alien) && !M.alien_talk_understand) - heard += M - - - if (length(heard)) - var/message_b - - message_b = "hsssss" - message_b = say_quote(message_b) - message_b = "[message_b]" - - rendered = "[voice_name] [message_b]" - - for (var/mob/M in heard) - M.show_message(rendered, 2) - - message = say_quote(message) - - rendered = "Hivemind, [name] [message_a]" - var/rendered2 = null - for (var/mob/M in player_list) - if (istype(M, /mob/new_player)) - continue - if (M.stat > 1 && istype(M, /mob/dead/observer)) - rendered2 = "Hivemind, [name] (Follow) [message_a]" - M.show_message(rendered2, 2) \ No newline at end of file + ..(message, speaking, verb, null, null, message_range, null) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm index 517a91a3501..2db6b56b75a 100644 --- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm +++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm @@ -74,7 +74,7 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds AttemptGrow() /obj/item/alien_embryo/proc/AttemptGrow(var/gib_on_success = 1) - var/list/candidates = get_candidates(BE_ALIEN,ALIEN_AFK_BRACKET,"alien","Syndicate") + var/list/candidates = get_candidates(BE_ALIEN,ALIEN_AFK_BRACKET,1) var/client/C = null // To stop clientless larva, we will check that our host has a client diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm index 04295be82da..b7bb4ee6dd2 100644 --- a/code/modules/mob/living/carbon/alien/special/facehugger.dm +++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm @@ -40,7 +40,7 @@ var/const/MAX_ACTIVE_TIME = 400 /obj/item/clothing/mask/facehugger/attack(mob/living/M as mob, mob/user as mob) ..() - user.before_take_item(src) + user.unEquip(src) Attach(M) /obj/item/clothing/mask/facehugger/examine(mob/user) @@ -55,7 +55,7 @@ var/const/MAX_ACTIVE_TIME = 400 if (sterile) user << "It looks like the proboscis has been removed." -/obj/item/clothing/mask/facehugger/attackby(var/obj/item/O,var/mob/m) +/obj/item/clothing/mask/facehugger/attackby(var/obj/item/O,var/mob/m, params) if(O.force) Die() return @@ -131,9 +131,12 @@ var/const/MAX_ACTIVE_TIME = 400 if(iscarbon(M)) var/mob/living/carbon/target = L if(target.wear_mask) - if(prob(20)) return 0 + if(prob(20)) + return 0 var/obj/item/clothing/W = target.wear_mask - target.before_take_item(W) + if(W.flags & NODROP) + return 0 + target.unEquip(W) target.visible_message("[src] tears [W] off of [target]'s face!", \ "[src] tears [W] off of [target]'s face!") @@ -162,7 +165,7 @@ var/const/MAX_ACTIVE_TIME = 400 var/mob/living/carbon/C = target if(C.wear_mask != src) return - + if(ishuman(target)) var/mob/living/carbon/human/H = target if((H.species.flags & IS_SYNTHETIC)) @@ -231,6 +234,9 @@ var/const/MAX_ACTIVE_TIME = 400 return /proc/CanHug(var/mob/M) + if(!M || !ismob(M)) + return 0 + if(M.stat == DEAD) return 0 @@ -252,4 +258,4 @@ var/const/MAX_ACTIVE_TIME = 400 gender = FEMALE /obj/item/clothing/mask/facehugger/lamarr/New()//to prevent deleting it if aliums are disabled - return \ No newline at end of file + return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/alien/special/snakeman.dm b/code/modules/mob/living/carbon/alien/special/snakeman.dm index d1d55895d88..7aa7b9d5db0 100644 --- a/code/modules/mob/living/carbon/alien/special/snakeman.dm +++ b/code/modules/mob/living/carbon/alien/special/snakeman.dm @@ -33,7 +33,7 @@ M.client.mob = new/mob/living/carbon/alien/humanoid/special/snakeman(new/obj/effect/snake_egg(src.loc)) visible_message("[src] injects [M] with an egg.") visible_message("The egg absorbs [M]") - M.mutations |= M_NOCLONE + M.mutations |= NOCLONE M.update_body() M.death() else diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm index abc980023f0..c8c7142fa69 100644 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ b/code/modules/mob/living/carbon/brain/MMI.dm @@ -21,7 +21,7 @@ var/mob/living/silicon/robot = null//Appears unused. var/obj/mecha = null//This does not appear to be used outside of reference in mecha.dm. - attackby(var/obj/item/O as obj, var/mob/user as mob) + attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(istype(O,/obj/item/brain) && !brainmob) //Time to stick a brain in it --NEO if(!O:brainmob) user << "\red You aren't sure where this brain came from, but you're pretty sure it's a useless brain." diff --git a/code/modules/mob/living/carbon/brain/brain.dm b/code/modules/mob/living/carbon/brain/brain.dm index f181cc05464..bbcd527386b 100644 --- a/code/modules/mob/living/carbon/brain/brain.dm +++ b/code/modules/mob/living/carbon/brain/brain.dm @@ -55,4 +55,7 @@ canmove = 1 use_me = 1 //If it can move, let it emote else canmove = 0 - return canmove \ No newline at end of file + return canmove + +/mob/living/carbon/brain/binarycheck() + return istype(loc, /obj/item/device/mmi/posibrain) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index 990f2971c58..12adf40d53e 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -3,7 +3,6 @@ desc = "A piece of juicy meat found in a persons head." icon = 'icons/obj/surgery.dmi' icon_state = "brain2" - flags = TABLEPASS force = 1.0 w_class = 1.0 throwforce = 1.0 diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm index 65bf8148a56..606959d5de8 100644 --- a/code/modules/mob/living/carbon/brain/life.dm +++ b/code/modules/mob/living/carbon/brain/life.dm @@ -193,7 +193,7 @@ proc/handle_regular_hud_updates() - if (stat == 2 || (M_XRAY in src.mutations)) + if (stat == 2 || (XRAY in src.mutations)) sight |= SEE_TURFS sight |= SEE_MOBS sight |= SEE_OBJS diff --git a/code/modules/mob/living/carbon/brain/say.dm b/code/modules/mob/living/carbon/brain/say.dm index 1e7a9da9a76..26dc7b30f3f 100644 --- a/code/modules/mob/living/carbon/brain/say.dm +++ b/code/modules/mob/living/carbon/brain/say.dm @@ -1,3 +1,4 @@ +//TODO: Convert this over for languages. /mob/living/carbon/brain/say(var/message) if (silent) return @@ -8,18 +9,31 @@ if(!(container && (istype(container, /obj/item/device/mmi) || istype(container, /obj/item/device/mmi/posibrain)))) return //No MMI, can't speak, bucko./N else - if ((department_radio_keys[copytext(message, 1, 3)] == "binary") && (container && istype(container, /obj/item/device/mmi/posibrain))) - message = copytext(message, 3) - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) - robot_talk(message) - return + var/datum/language/speaking = parse_language(message) + if(speaking) + message = copytext(message, 2+length(speaking.key)) + var/verb = "says" + var/ending = copytext(message, length(message)) + if (speaking) + verb = speaking.get_spoken_verb(ending) + else + if(ending=="!") + verb=pick("exclaims","shouts","yells") + if(ending=="?") + verb="asks" + if(prob(emp_damage*4)) if(prob(10))//10% chane to drop the message entirely return else message = Gibberish(message, (emp_damage*6))//scrambles the message, gets worse when emp_damage is higher + + if(speaking && speaking.flags & HIVEMIND) + speaking.broadcast(src,trim(message)) + return + if(istype(container, /obj/item/device/mmi/radio_enabled)) var/obj/item/device/mmi/radio_enabled/R = container if(R.radio) - spawn(0) R.radio.hear_talk(src, sanitize(message)) - ..() \ No newline at end of file + spawn(0) R.radio.hear_talk(src, trim(sanitize(message)), verb, speaking) + ..(trim(message), speaking, verb) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 58fff0705ce..279755cc813 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -17,7 +17,7 @@ src.nutrition -= HUNGER_FACTOR/10 if(src.m_intent == "run") src.nutrition -= HUNGER_FACTOR/10 - if((M_FAT in src.mutations) && src.m_intent == "run" && src.bodytemperature <= 360) + if((FAT in src.mutations) && src.m_intent == "run" && src.bodytemperature <= 360) src.bodytemperature += 2 // Moving around increases germ_level faster @@ -78,7 +78,10 @@ /mob/living/carbon/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/def_zone = null) - if(status_flags & GODMODE) return 0 //godmode + if(status_flags & GODMODE) //godmode + return 0 + if(NO_SHOCK in mutations) //shockproof + return 0 shock_damage *= siemens_coeff if (shock_damage<1) return 0 @@ -99,8 +102,14 @@ "\red You feel a powerful shock course through your body!", \ "\red You hear a heavy electrical crack." \ ) - Stun(10)//This should work for now, more is really silly and makes you lay there forever - Weaken(10) + jitteriness += 1000 //High numbers for violent convulsions + do_jitter_animation(jitteriness) + stuttering += 2 + Stun(2) + spawn(20) + jitteriness -= 990 //Still jittery, but vastly less + Stun(3) + Weaken(3) if (shock_damage > 200) src.visible_message( "\red [src] was arc flashed by the [source]!", \ @@ -378,11 +387,13 @@ throw_mode_off() if(usr.stat || !target) return - if(target.type == /obj/screen) return + if(target.type == /obj/screen) + return var/atom/movable/item = src.get_active_hand() - if(!item) return + if(!item || (item.flags & NODROP)) + return if (istype(item, /obj/item/weapon/grab)) var/obj/item/weapon/grab/G = item @@ -404,10 +415,10 @@ else M.LAssailant = usr - if(!item) return //Grab processing has a chance of returning null - - item.layer = initial(item.layer) - u_equip(item) + if(!item) + return //Grab processing has a chance of returning null + if(!ismob(item)) //Honk mobs don't have a dropped() proc honk + unEquip(item) update_icons() if (istype(usr, /mob/living/carbon)) //Check if a carbon mob is throwing. Modify/remove this line as required. @@ -419,6 +430,7 @@ //actually throw it! if (item) + item.layer = initial(item.layer) src.visible_message("\red [src] has thrown [item].") if(!src.lastarea) @@ -437,10 +449,6 @@ item.throw_at(target, item.throw_range, item.throw_speed, src) -/mob/living/carbon/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) - ..() - bodytemperature = max(bodytemperature, BODYTEMP_HEAT_DAMAGE_LIMIT+10) - /mob/living/carbon/can_use_hands() if(handcuffed) return 0 @@ -453,29 +461,34 @@ return 1 return -/mob/living/carbon/u_equip(obj/item/W as obj) - if(!W) return 0 +/mob/living/carbon/unEquip(obj/item/I) //THIS PROC DID NOT CALL ..() + . = ..() //Sets the default return value to what the parent returns. + if(!. || !I) //We don't want to set anything to null if the parent returned 0. + return - else if (W == handcuffed) + if(I == back) + back = null + update_inv_back(0) + else if(I == wear_mask) + if(istype(src, /mob/living/carbon/human)) //If we don't do this hair won't be properly rebuilt. + return + wear_mask = null + update_inv_wear_mask(0) + else if(I == handcuffed) handcuffed = null - update_inv_handcuffed() - - else if (W == legcuffed) + update_inv_handcuffed(1) + else if(I == legcuffed) legcuffed = null - update_inv_legcuffed() - else - ..() - - return + update_inv_legcuffed(1) /mob/living/carbon/show_inv(mob/living/carbon/user as mob) user.set_machine(src) var/dat = {"
[name]


-
Head(Mask): [(wear_mask ? wear_mask : "Nothing")] -
Left Hand: [(l_hand ? l_hand : "Nothing")] -
Right Hand: [(r_hand ? r_hand : "Nothing")] +
Head(Mask): [(wear_mask && !(wear_mask.flags & ABSTRACT)) ? wear_mask : "Nothing"] +
Left Hand: [(l_hand && !(l_hand.flags & ABSTRACT)) ? l_hand : "Nothing"] +
Right Hand: [(r_hand && !(r_hand.flags & ABSTRACT)) ? r_hand : "Nothing"]
Back: [(back ? back : "Nothing")] [((istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank) && !( internal )) ? text(" Set Internal", src) : "")]
[(handcuffed ? text("Handcuffed") : text("Not Handcuffed"))]
[(internal ? text("Remove Internal") : "")] @@ -579,4 +592,7 @@ return /mob/living/carbon/proc/canBeHandcuffed() - return 0 \ No newline at end of file + return 0 + +/mob/living/carbon/is_muzzled() + return(istype(src.wear_mask, /obj/item/clothing/mask/muzzle)) diff --git a/code/modules/mob/living/carbon/give.dm b/code/modules/mob/living/carbon/give.dm index 5a28b8af193..63dbfac240c 100644 --- a/code/modules/mob/living/carbon/give.dm +++ b/code/modules/mob/living/carbon/give.dm @@ -1,18 +1,15 @@ -/mob/living/carbon/verb/give() +/mob/living/carbon/verb/give(var/mob/living/carbon/target in oview(1)) set category = "IC" set name = "Give" - set src in view(1) - if(src.stat == 2 || usr.stat == 2 || src.client == null) - return - if(src == usr) - usr << "\red I feel stupider, suddenly." + + if(target.stat == 2 || usr.stat == 2|| target.client == null) return var/obj/item/I if(!usr.hand && usr.r_hand == null) - usr << "\red You don't have anything in your right hand to give to [src.name]" + usr << " You don't have anything in your right hand to give to [target.name]" return if(usr.hand && usr.l_hand == null) - usr << "\red You don't have anything in your left hand to give to [src.name]" + usr << " You don't have anything in your left hand to give to [target.name]" return if(usr.hand) I = usr.l_hand @@ -20,38 +17,41 @@ I = usr.r_hand if(!I) return - if(src.r_hand == null || src.l_hand == null) - switch(alert(src,"[usr] wants to give you \a [I]?",,"Yes","No")) + if((I.flags & NODROP) || (I.flags & ABSTRACT)) + usr << "That's not exactly something you can give." + return + if(target.r_hand == null || target.l_hand == null) + switch(alert(target,"[usr] wants to give you \a [I]?",,"Yes","No")) if("Yes") if(!I) return if(!Adjacent(usr)) - usr << "\red You need to stay in reaching distance while giving an object." - src << "\red [usr.name] moved too far away." + usr << " You need to stay in reaching distance while giving an object." + target << " [usr.name] moved too far away." return if((usr.hand && usr.l_hand != I) || (!usr.hand && usr.r_hand != I)) - usr << "\red You need to keep the item in your active hand." - src << "\red [usr.name] seem to have given up on giving \the [I.name] to you." + usr << " You need to keep the item in your active hand." + target << " [usr.name] seem to have given up on giving \the [I.name] to you." return - if(src.r_hand != null && src.l_hand != null) - src << "\red Your hands are full." - usr << "\red Their hands are full." + if(target.r_hand != null && target.l_hand != null) + target << " Your hands are full." + usr << " Their hands are full." return else usr.drop_item() - if(src.r_hand == null) - src.r_hand = I + if(target.r_hand == null) + target.r_hand = I else - src.l_hand = I - I.loc = src + target.l_hand = I + I.loc = target I.layer = 20 - I.add_fingerprint(src) + I.add_fingerprint(target) src.update_inv_l_hand() src.update_inv_r_hand() usr.update_inv_l_hand() usr.update_inv_r_hand() - src.visible_message("\blue [usr.name] handed \the [I.name] to [src.name].") + target.visible_message(" [usr.name] handed \the [I.name] to [target.name].") if("No") - src.visible_message("\red [usr.name] tried to hand [I.name] to [src.name] but [src.name] didn't want it.") + target.visible_message(" [usr.name] tried to hand [I.name] to [target.name] but [target.name] didn't want it.") else - usr << "\red [src.name]'s hands are full." \ No newline at end of file + usr << " [target.name]'s hands are full." \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 08fe26ce77f..43ac690597d 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -151,7 +151,7 @@ return /mob/living/carbon/human/proc/ChangeToHusk() - if(M_HUSK in mutations) return + if(HUSK in mutations) return if(f_style) f_style = "Shaved" //we only change the icon_state of the hair datum, so it doesn't mess up their UI/UE @@ -159,7 +159,7 @@ h_style = "Bald" update_hair(0) - mutations.Add(M_HUSK) + mutations.Add(HUSK) status_flags |= DISFIGURED //makes them unknown without fucking up other stuff like admintools update_body(0) update_mutantrace() @@ -167,5 +167,5 @@ /mob/living/carbon/human/proc/Drain() ChangeToHusk() - mutations |= M_NOCLONE + mutations |= NOCLONE return diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 28afe49ab45..8ef4ea47268 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -9,7 +9,9 @@ if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_' act = copytext(act,1,length(act)) - var/muzzled = istype(src.wear_mask, /obj/item/clothing/mask/muzzle) + var/muzzled = is_muzzled() + if(sdisabilities & MUTE || silent) + muzzled = 1 //var/m_type = 1 for (var/obj/item/weapon/implant/I in src) @@ -18,69 +20,117 @@ if(src.stat == 2.0 && (act != "deathgasp")) return + + //Emote Cooldown System (it's so simple!) + // proc/handle_emote_CD() located in [code\modules\mob\emote.dm] + var/on_CD = 0 + switch(act) + //Cooldown-inducing emotes + if("ping","buzz","beep") + if (species.name == "Machine") //Only Machines can beep, ping, and buzz + on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm + else //Everyone else fails, skip the emote attempt + return + if("squish") + if(species.name == "Slime People") //Only Slime People can squish + on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm + else //Everyone else fails, skip the emote attempt + return + if("scream", "fart", "flip") + on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm + //Everything else, including typos of the above emotes + else + on_CD = 0 //If it doesn't induce the cooldown, we won't check for the cooldown + + if(on_CD == 1) // Check if we need to suppress the emote attempt. + return // Suppress emote, you're still cooling off. + //--FalseIncarnate + switch(act) if("ping") - if (species.name == "Machine") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null + var/M = null + if(param) + for (var/mob/A in view(null, null)) + if (param == A.name) + M = A + break + if(!M) + param = null - if (param) - message = "[src] pings at [param]." - else - message = "[src] pings." - playsound(src.loc, 'sound/machines/ping.ogg', 50, 0) - m_type = 1 + if (param) + message = "[src] pings at [param]." else - if (!species.name == "Machine") - return + message = "[src] pings." + playsound(src.loc, 'sound/machines/ping.ogg', 50, 0) + m_type = 1 if("buzz") - if (species.name == "Machine") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null + var/M = null + if(param) + for (var/mob/A in view(null, null)) + if (param == A.name) + M = A + break + if(!M) + param = null - if (param) - message = "[src] buzzes at [param]." - else - message = "[src] buzzes." - playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0) - m_type = 1 + if (param) + message = "[src] buzzes at [param]." else - if (!species.name == "Machine") - return + message = "[src] buzzes." + playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0) + m_type = 1 if("beep") - if(species.name == "Machine") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null + var/M = null + if(param) + for (var/mob/A in view(null, null)) + if (param == A.name) + M = A + break + if(!M) + param = null - if (param) - message = "[src] beeps at [param]." - else - message = "[src] beeps." - playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) - m_type = 1 + if (param) + message = "[src] beeps at [param]." else - if (!species.name == "Machine") + message = "[src] beeps." + playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) + m_type = 1 + + if("squish") + var/M = null + if(param) + for (var/mob/A in view(null, null)) + if (param == A.name) + M = A + break + if(!M) + param = null + + if (param) + message = "[src] squishes at [param]." + else + message = "[src] squishes." + playsound(src.loc, 'sound/effects/slime_squish.ogg', 50, 0) //Credit to DrMinky (freesound.org) for the sound. + m_type = 1 + + if("wag") + if(species.bodyflags & TAIL_WAGGING) + if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL) && !istype(wear_suit, /obj/item/clothing/suit/space)) + message = "[src] starts wagging \his tail." + src.start_tail_wagging(1) + else return + else + return + + if("swag") + if(species.bodyflags & TAIL_WAGGING) + message = "[src] stops wagging \his tail." + src.stop_tail_wagging(1) + else + return if ("airguitar") if (!src.restrained()) @@ -113,7 +163,7 @@ m_type = 1 if ("custom") - var/input = copytext(sanitize(input("Choose an emote to display.") as text|null),1,MAX_MESSAGE_LEN) + var/input = sanitize(copytext(input("Choose an emote to display.") as text|null,1,MAX_MESSAGE_LEN)) if (!input) return var/input2 = input("Is this a visible or hearable emote?") in list("Visible","Hearable") @@ -185,6 +235,31 @@ if(miming) m_type = 1 + if ("flip") + m_type = 1 + if (!src.restrained()) + var/M = null + if (param) + for (var/mob/A in view(1, null)) + if (param == A.name) + M = A + break + if (M == src) + M = null + + if (M) + if(src.lying || src.weakened) + message = "[src] flops and flails around on the floor." + else + message = "[src] flips in [M]'s general direction." + src.SpinAnimation(5,1) + else + if(src.lying || src.weakened) + message = "[src] flops and flails around on the floor." + else + message = "[src] does a flip!" + src.SpinAnimation(5,1) + if ("aflap") if (!src.restrained()) message = "[src] flaps his wings ANGRILY!" @@ -228,17 +303,16 @@ m_type = 1 if ("cough") - if(!reagents.has_reagent("dextromethorphan")) - if(miming) - message = "[src] appears to cough!" - m_type = 1 + if(miming) + message = "[src] appears to cough!" + m_type = 1 + else + if (!muzzled) + message = "[src] coughs!" + m_type = 2 else - if (!muzzled) - message = "[src] coughs!" - m_type = 2 - else - message = "[src] makes a strong noise." - m_type = 2 + message = "[src] makes a strong noise." + m_type = 2 if ("frown") message = "[src] frowns." @@ -634,75 +708,55 @@ // Needed for M_TOXIC_FART if("fart") - if(world.time-lastFart >= 600) -// playsound(src.loc, 'sound/effects/fart.ogg', 50, 1, -3) //Admins still vote no to fun - if(M_TOXIC_FARTS in mutations) - message = "[src] unleashes a [pick("horrible","terrible","foul","disgusting","awful")] fart." - else - message = "[src] [pick("passes wind","farts")]." - m_type = 2 - - var/turf/location = get_turf(src) - var/aoe_range=2 // Default - if(M_SUPER_FART in mutations) - aoe_range+=3 //Was 5 - - /* // If we're wearing a suit, don't blast or gas those around us. - var/wearing_suit=0 - var/wearing_mask=0 - if(wear_suit && wear_suit.body_parts_covered & LOWER_TORSO) - wearing_suit=1 - if (internal != null && wear_mask && (wear_mask.flags & MASKINTERNALS)) - wearing_mask=1 */ - - // Process toxic farts first. - if(M_TOXIC_FARTS in mutations) - for(var/mob/M in range(location,aoe_range)) - if (M.internal != null && M.wear_mask && (M.wear_mask.flags & MASKINTERNALS)) - continue - if(!airborne_can_reach(location,M,aoe_range)) - continue - // Now, we don't have this: - //new /obj/effects/fart_cloud(T,L) - // But: - // <[REDACTED]> so, what it does is...imagine a 3x3 grid with the person in the center. When someone uses the emote *fart (it's not a spell style ability and has no cooldown), then anyone in the 8 tiles AROUND the person who uses it - // <[REDACTED]> gets between 1 and 10 units of jenkem added to them...we obviously don't have Jenkem, but Space Drugs do literally the same exact thing as Jenkem - // <[REDACTED]> the user, of course, isn't impacted because it's not an actual smoke cloud - // So, let's give 'em space drugs. - if (M == src) - continue - M.reagents.add_reagent("space_drugs",rand(1,10)) - /* - var/datum/effect/effect/system/smoke_spread/chem/fart/S = new /datum/effect/effect/system/smoke_spread/chem/fart - S.attach(location) - S.set_up(src, 10, 0, location) - spawn(0) - S.start() - sleep(10) - S.start() - */ - if(M_SUPER_FART in mutations) - visible_message("\red [name] hunches down and grits their teeth!") - if(do_after(usr,30)) - visible_message("\red [name] unleashes a [pick("tremendous","gigantic","colossal")] fart!","You hear a [pick("tremendous","gigantic","colossal")] fart.") - //playsound(L.loc, 'superfart.ogg', 50, 0) - for(var/mob/living/V in range(location,aoe_range)) - shake_camera(V,10,5) - if (V == src) - continue - if(!airborne_can_reach(get_turf(src), get_turf(V))) - continue - V << "\red You are sent flying!" - V.Weaken(5) // why the hell was this set to 12 christ - step_away(V,location,15) - step_away(V,location,15) - step_away(V,location,15) - else - usr << "\red You were interrupted and couldn't fart! Rude!" - lastFart=world.time +// playsound(src.loc, 'sound/effects/fart.ogg', 50, 1, -3) //Admins still vote no to fun + if(TOXIC_FARTS in mutations) + message = "[src] unleashes a [pick("horrible","terrible","foul","disgusting","awful")] fart." else - message = "[src] strains, and nothing happens." - m_type = 1 + message = "[src] [pick("passes wind","farts")]." + m_type = 2 + + var/turf/location = get_turf(src) + var/aoe_range=2 // Default + if(SUPER_FART in mutations) + aoe_range+=3 //Was 5 + + // Process toxic farts first. + if(TOXIC_FARTS in mutations) + for(var/mob/M in range(location,aoe_range)) + if (M.internal != null && M.wear_mask && (M.wear_mask.flags & MASKINTERNALS)) + continue + if(!airborne_can_reach(location,M,aoe_range)) + continue + // Now, we don't have this: + //new /obj/effects/fart_cloud(T,L) + // But: + // <[REDACTED]> so, what it does is...imagine a 3x3 grid with the person in the center. When someone uses the emote *fart (it's not a spell style ability and has no cooldown), then anyone in the 8 tiles AROUND the person who uses it + // <[REDACTED]> gets between 1 and 10 units of jenkem added to them...we obviously don't have Jenkem, but Space Drugs do literally the same exact thing as Jenkem + // <[REDACTED]> the user, of course, isn't impacted because it's not an actual smoke cloud + // So, let's give 'em space drugs. + if (M == src) + continue + M.reagents.add_reagent("space_drugs",rand(1,10)) + + if(SUPER_FART in mutations) + visible_message("\red [name] hunches down and grits their teeth!") + if(do_after(usr,30)) + visible_message("\red [name] unleashes a [pick("tremendous","gigantic","colossal")] fart!","You hear a [pick("tremendous","gigantic","colossal")] fart.") + //playsound(L.loc, 'superfart.ogg', 50, 0) + for(var/mob/living/V in range(location,aoe_range)) + shake_camera(V,10,5) + if (V == src) + continue + if(!airborne_can_reach(get_turf(src), get_turf(V))) + continue + V << "\red You are sent flying!" + V.Weaken(5) // why the hell was this set to 12 christ + step_away(V,location,15) + step_away(V,location,15) + step_away(V,location,15) + else + usr << "\red You were interrupted and couldn't fart! Rude!" + if ("help") src << "blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough,\ncry, custom, deathgasp, drool, eyebrow, frown, gasp, giggle, groan, grumble, handshake, hug-(none)/mob, glare-(none)/mob,\ngrin, laugh, look-(none)/mob, moan, mumble, nod, pale, point-atom, raise, salute, shake, shiver, shrug,\nsigh, signal-#1-10, smile, sneeze, sniff, snore, stare-(none)/mob, tremble, twitch, twitch_s, whimper,\nwink, yawn" @@ -740,11 +794,11 @@ set desc = "Sets a description which will be shown when someone examines you." set category = "IC" - pose = copytext(sanitize(input(usr, "This is [src]. \He is...", "Pose", null) as text), 1, MAX_MESSAGE_LEN) + pose = sanitize(copytext(input(usr, "This is [src]. \He is...", "Pose", null) as text, 1, MAX_MESSAGE_LEN)) /mob/living/carbon/human/verb/set_flavor() set name = "Set Flavour Text" set desc = "Sets an extended description of your character's features." set category = "IC" - flavor_text = copytext(sanitize(input(usr, "Please enter your new flavour text.", "Flavour text", null) as text), 1) + flavor_text = sanitize(copytext(input(usr, "Please enter your new flavour text.", "Flavour text", null) as text, 1)) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 3f8953c397a..c107068955f 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -67,8 +67,8 @@ var/tie_msg if(istype(w_uniform,/obj/item/clothing/under)) var/obj/item/clothing/under/U = w_uniform - if(U.hastie) - tie_msg += " with \icon[U.hastie] \a [U.hastie]" + if(U.accessories.len) + tie_msg += " with [lowertext(english_list(U.accessories))]" if(w_uniform.blood_DNA) msg += "[t_He] [t_is] wearing \icon[w_uniform] [w_uniform.gender==PLURAL?"some":"a"] blood-stained [w_uniform.name][tie_msg]!\n" @@ -104,14 +104,14 @@ msg += "[t_He] [t_has] \icon[back] \a [back] on [t_his] back.\n" //left hand - if(l_hand) + if(l_hand && !(l_hand.flags & ABSTRACT)) if(l_hand.blood_DNA) msg += "[t_He] [t_is] holding \icon[l_hand] [l_hand.gender==PLURAL?"some":"a"] blood-stained [l_hand.name] in [t_his] left hand!\n" else msg += "[t_He] [t_is] holding \icon[l_hand] \a [l_hand] in [t_his] left hand.\n" //right hand - if(r_hand) + if(r_hand && !(r_hand.flags & ABSTRACT)) if(r_hand.blood_DNA) msg += "[t_He] [t_is] holding \icon[r_hand] [r_hand.gender==PLURAL?"some":"a"] blood-stained [r_hand.name] in [t_his] right hand!\n" else @@ -130,7 +130,9 @@ //handcuffed? if(handcuffed) - if(istype(handcuffed, /obj/item/weapon/handcuffs/cable)) + if(istype(handcuffed, /obj/item/weapon/restraints/handcuffs/cable/zipties)) + msg += "[t_He] [t_is] \icon[handcuffed] restrained with zipties!\n" + else if(istype(handcuffed, /obj/item/weapon/restraints/handcuffs/cable)) msg += "[t_He] [t_is] \icon[handcuffed] restrained with cable!\n" else msg += "[t_He] [t_is] \icon[handcuffed] handcuffed!\n" @@ -203,7 +205,7 @@ if(suiciding) msg += "[t_He] appears to have commited suicide... there is no hope of recovery.\n" - if(M_DWARF in mutations) + if(DWARF in mutations) msg += "[t_He] [t_is] a halfling!\n" var/distance = get_dist(usr,src) @@ -211,7 +213,7 @@ distance = 1 if (src.stat) msg += "[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.\n" - if((stat == 2 || src.health < config.health_threshold_crit) && distance <= 3) + if((stat == 2 || src.health <= config.health_threshold_crit) && distance <= 3) msg += "[t_He] does not appear to be breathing.\n" if(istype(usr, /mob/living/carbon/human) && !usr.stat && distance <= 1) for(var/mob/O in viewers(usr.loc, null)) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 1c0feaaef05..328197ce46b 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -9,6 +9,40 @@ var/datum/species/species //Contains icon generation and language information, set during New(). var/embedded_flag //To check if we've need to roll for damage on movement while an item is imbedded in us. +/mob/living/carbon/human/New(var/new_loc, var/new_species = null, var/delay_ready_dna=0) + if(!species) + if(new_species) + set_species(new_species,null,1) + else + set_species() + + var/datum/reagents/R = new/datum/reagents(1000) + reagents = R + R.my_atom = src + + hud_list[HEALTH_HUD] = image('icons/mob/hud.dmi', src, "hudhealth100") + hud_list[STATUS_HUD] = image('icons/mob/hud.dmi', src, "hudhealthy") + hud_list[ID_HUD] = image('icons/mob/hud.dmi', src, "hudunknown") + hud_list[WANTED_HUD] = image('icons/mob/hud.dmi', src, "hudblank") + hud_list[IMPLOYAL_HUD] = image('icons/mob/hud.dmi', src, "hudblank") + hud_list[IMPCHEM_HUD] = image('icons/mob/hud.dmi', src, "hudblank") + hud_list[IMPTRACK_HUD] = image('icons/mob/hud.dmi', src, "hudblank") + hud_list[SPECIALROLE_HUD] = image('icons/mob/hud.dmi', src, "hudblank") + hud_list[STATUS_HUD_OOC] = image('icons/mob/hud.dmi', src, "hudhealthy") + hud_list[NATIONS_HUD] = image('icons/mob/hud.dmi', src, "hudblank") + + ..() + + if(dna) + dna.real_name = real_name + + prev_gender = gender // Debug for plural genders + make_blood() + + // Set up DNA. + if(!delay_ready_dna) + dna.ready_dna(src) + /mob/living/carbon/human/dummy real_name = "Test Dummy" status_flags = GODMODE|CANPUSH @@ -49,8 +83,6 @@ /mob/living/carbon/human/grey/New(var/new_loc) ..(new_loc, "Grey") - spell_list += new /obj/effect/proc_holder/spell/wizard/targeted/remotetalk - /mob/living/carbon/human/human/New(var/new_loc) ..(new_loc, "Human") @@ -63,50 +95,6 @@ h_style = "blue IPC screen" ..(new_loc, "Machine") -/mob/living/carbon/human/New(var/new_loc, var/new_species = null, var/delay_ready_dna=0) - if(!species) - if(new_species) - set_species(new_species,null,1) - else - set_species() - - if(species.language) - var/datum/language/L = all_languages[species.language] - if(L) - languages += L - - var/datum/reagents/R = new/datum/reagents(1000) - reagents = R - R.my_atom = src - - if(!dna) - dna = new /datum/dna(null) - dna.species=species.name - - hud_list[HEALTH_HUD] = image('icons/mob/hud.dmi', src, "hudhealth100") - hud_list[STATUS_HUD] = image('icons/mob/hud.dmi', src, "hudhealthy") - hud_list[ID_HUD] = image('icons/mob/hud.dmi', src, "hudunknown") - hud_list[WANTED_HUD] = image('icons/mob/hud.dmi', src, "hudblank") - hud_list[IMPLOYAL_HUD] = image('icons/mob/hud.dmi', src, "hudblank") - hud_list[IMPCHEM_HUD] = image('icons/mob/hud.dmi', src, "hudblank") - hud_list[IMPTRACK_HUD] = image('icons/mob/hud.dmi', src, "hudblank") - hud_list[SPECIALROLE_HUD] = image('icons/mob/hud.dmi', src, "hudblank") - hud_list[STATUS_HUD_OOC] = image('icons/mob/hud.dmi', src, "hudhealthy") - hud_list[NATIONS_HUD] = image('icons/mob/hud.dmi', src, "hudblank") - - ..() - - if(dna) - dna.real_name = real_name - - prev_gender = gender // Debug for plural genders - make_blood() - - // Set up DNA. - if(!delay_ready_dna) - dna.ready_dna(src) - - /mob/living/carbon/human/Bump(atom/movable/AM as mob|obj, yes) if ((!( yes ) || now_pushing)) return @@ -155,8 +143,8 @@ slime.UpdateFeed() return - if(istype(tmob, /mob/living/carbon/human) && (M_FAT in tmob.mutations)) - if(prob(40) && !(M_FAT in src.mutations)) + if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) + if(prob(40) && !(FAT in src.mutations)) src << "\red You fail to push [tmob]'s fat ass out of the way." now_pushing = 0 return @@ -217,8 +205,8 @@ stat("Distribution Pressure", internal.distribute_pressure) if(mind) if(mind.changeling) - stat("Chemical Storage", mind.changeling.chem_charges) - stat("Genetic Damage Time", mind.changeling.geneticdamage) + stat("Chemical Storage", "[mind.changeling.chem_charges]/[mind.changeling.chem_storage]") + stat("Absorbed DNA", mind.changeling.absorbedcount) if (istype(wear_suit, /obj/item/clothing/suit/space/space_ninja)&&wear_suit:s_initialized) stat("Energy Charge", (wear_suit:cell:charge)) @@ -380,6 +368,7 @@ if(M.melee_damage_upper == 0) M.emote("[M.friendly] [src]") else + M.do_attack_animation(src) if(M.attack_sound) playsound(loc, M.attack_sound, 50, 1, 1) for(var/mob/O in viewers(src, null)) @@ -396,6 +385,25 @@ apply_damage(damage, BRUTE, affecting, armor, M.name) if(armor >= 2) return +/mob/living/carbon/human/attack_larva(mob/living/carbon/alien/larva/L as mob) + + switch(L.a_intent) + if("help") + visible_message("[L] rubs its head against [src].") + + + else + L.do_attack_animation(src) + var/damage = rand(1, 3) + visible_message("[L] bites [src]!", \ + "[L] bites [src]!") + playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) + + if(stat != DEAD) + L.amount_grown = min(L.amount_grown + damage, L.max_grown) + var/datum/organ/external/affecting = get_organ(ran_zone(L.zone_sel.selecting)) + var/armor_block = run_armor_check(affecting, "melee") + apply_damage(damage, BRUTE, affecting, armor_block) /mob/living/carbon/human/proc/is_loyalty_implanted(mob/living/carbon/human/M) for(var/L in M.contents) @@ -410,9 +418,9 @@ if (health > -100) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red The [M.name] glomps []!", src), 1) + M.do_attack_animation(src) + visible_message("The [M.name] glomps [src]!", \ + "The [M.name] glomps [src]!") var/damage = rand(1, 3) @@ -496,28 +504,28 @@ var/dat = {"
[name]


-
Head(Mask): [(wear_mask ? wear_mask : "Nothing")] -
Left Hand: [(l_hand ? l_hand : "Nothing")] -
Right Hand: [(r_hand ? r_hand : "Nothing")] -
Gloves: [(gloves ? gloves : "Nothing")] -
Eyes: [(glasses ? glasses : "Nothing")] -
Left Ear: [(l_ear ? l_ear : "Nothing")] -
Right Ear: [(r_ear ? r_ear : "Nothing")] -
Head: [(head ? head : "Nothing")] -
Shoes: [(shoes ? shoes : "Nothing")] -
Belt: [(belt ? belt : "Nothing")] [((istype(wear_mask, /obj/item/clothing/mask) && istype(belt, /obj/item/weapon/tank) && !( internal )) ? text(" Set Internal", src) : "")] -
Uniform: [(w_uniform ? w_uniform : "Nothing")] [(suit) ? ((suit.has_sensor == 1) ? text(" Sensors", src) : "") :] -
(Exo)Suit: [(wear_suit ? wear_suit : "Nothing")] -
Back: [(back ? back : "Nothing")] [((istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank) && !( internal )) ? text(" Set Internal", src) : "")] -
ID: [(wear_id ? wear_id : "Nothing")] -
PDA: [(wear_pda ? wear_pda : "Nothing")] -
Suit Storage: [(s_store ? s_store : "Nothing")] -

Left Pocket ([l_store ? (pickpocket ? l_store.name : "Full") : "Empty"]) -
Right Pocket ([r_store ? (pickpocket ? r_store.name : "Full") : "Empty"]) +
Head(Mask): [(wear_mask && !(wear_mask.flags & ABSTRACT)) ? wear_mask : "Nothing"] +
Left Hand: [(l_hand && !(l_hand.flags & ABSTRACT)) ? l_hand : "Nothing"] +
Right Hand: [(r_hand && !(r_hand.flags&ABSTRACT)) ? r_hand : "Nothing"] +
Gloves: [(gloves && !(gloves.flags & ABSTRACT)) ? gloves : "Nothing"] +
Eyes: [(glasses && !(glasses.flags & ABSTRACT)) ? glasses : "Nothing"] +
Left Ear: [(l_ear && !(l_ear.flags & ABSTRACT)) ? l_ear : "Nothing"] +
Right Ear: [(r_ear && !(r_ear.flags & ABSTRACT)) ? r_ear : "Nothing"] +
Head: [(head && !(head.flags & ABSTRACT)) ? head : "Nothing"] +
Shoes: [(shoes && !(shoes.flags & ABSTRACT)) ? shoes : "Nothing"] +
Belt: [(belt && !(belt.flags & ABSTRACT)) ? belt : "Nothing"] [((istype(wear_mask, /obj/item/clothing/mask) && istype(belt, /obj/item/weapon/tank) && !( internal )) ? text(" Set Internal", src) : "")] +
Uniform: [(w_uniform && !(w_uniform.flags & ABSTRACT)) ? w_uniform : "Nothing"] [(suit) ? ((suit.has_sensor == 1) ? text(" Sensors", src) : "") :] +
(Exo)Suit: [(wear_suit && !(wear_suit.flags & ABSTRACT)) ? wear_suit : "Nothing"] +
Back: [(back && !(back.flags & ABSTRACT)) ? back : "Nothing"] [((istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank) && !( internal )) ? text(" Set Internal", src) : "")] +
ID: [(wear_id && !(wear_id.flags & ABSTRACT)) ? wear_id : "Nothing"] +
PDA: [(wear_pda && !(wear_pda.flags & ABSTRACT)) ? wear_pda : "Nothing"] +
Suit Storage: [(s_store && !(s_store.flags & ABSTRACT)) ? s_store : "Nothing"] +

Left Pocket ([(l_store && !(l_store.flags & ABSTRACT)) ? (pickpocket ? l_store.name : "Full") : "Empty"]) +
Right Pocket ([(r_store && !(r_store.flags & ABSTRACT)) ? (pickpocket ? r_store.name : "Full") : "Empty"])
Empty Both Pockets

[(handcuffed ? text("Handcuffed") : text("Not Handcuffed"))]
[(legcuffed ? text("Legcuffed") : text(""))] - [(suit) ? ((suit.hastie) ? text("
Remove Accessory", src) : "") :] + [(suit) ? ((suit.accessories.len) ? text("
Remove Accessory", src) : "") :] [(internal ? text("
Remove Internal") : "")]
Remove Splints
Refresh @@ -538,6 +546,20 @@ var/obj/vehicle/V = AM V.RunOver(src) +// Get rank from ID, ID inside PDA, PDA, ID in wallet, etc. +/mob/living/carbon/human/proc/get_authentification_rank(var/if_no_id = "No id", var/if_no_job = "No job") + var/obj/item/device/pda/pda = wear_id + if (istype(pda)) + if (pda.id) + return pda.id.rank + else + return pda.ownrank + else + var/obj/item/weapon/card/id/id = get_idcard() + if(id) + return id.rank ? id.rank : if_no_job + else + return if_no_id //gets assignment from ID or ID inside PDA or PDA itself //Useful when player do something with computers @@ -588,7 +610,7 @@ //Returns "Unknown" if facially disfigured and real_name if not. Useful for setting name when polyacided or when updating a human's name variable /mob/living/carbon/human/proc/get_face_name() var/datum/organ/external/head/head = get_organ("head") - if( !head || head.disfigured || (head.status & ORGAN_DESTROYED) || !real_name || (M_HUSK in mutations) ) //disfigured. use id-name if possible + if( !head || head.disfigured || (head.status & ORGAN_DESTROYED) || !real_name || (HUSK in mutations) ) //disfigured. use id-name if possible return "Unknown" return real_name @@ -614,7 +636,10 @@ //Removed the horrible safety parameter. It was only being used by ninja code anyways. //Now checks siemens_coefficient of the affected area by default /mob/living/carbon/human/electrocute_act(var/shock_damage, var/obj/source, var/base_siemens_coeff = 1.0, var/def_zone = null) - if(status_flags & GODMODE) return 0 //godmode + if(status_flags & GODMODE) //godmode + return 0 + if(NO_SHOCK in mutations) //shockproof + return 0 if (!def_zone) def_zone = pick("l_hand", "r_hand") @@ -640,20 +665,22 @@ var/obj/item/pocket_item = (pocket_id == slot_r_store ? src.r_store : src.l_store) var/obj/item/place_item = usr.get_active_hand() // Item to place in the pocket, if it's empty - if(pocket_item) + if(pocket_item && !(pocket_item.flags & ABSTRACT)) + if(pocket_item.flags & NODROP) + usr << "You try to empty [src]'s [pocket_side] pocket, it seems to be stuck!" usr << "You try to empty [src]'s [pocket_side] pocket." - else if(place_item && place_item.mob_can_equip(src, pocket_id, 1)) + else if(place_item && place_item.mob_can_equip(src, pocket_id, 1) && !(place_item.flags & ABSTRACT)) usr << "You try to place [place_item] into [src]'s [pocket_side] pocket." else return if(do_mob(usr, src, STRIP_DELAY)) if(pocket_item) - u_equip(pocket_item) + unEquip(pocket_item) usr.put_in_hands(pocket_item) else if(place_item) - usr.u_equip(place_item) + usr.unEquip(place_item) equip_to_slot_if_possible(place_item, pocket_id, 0, 1) // Update strip window @@ -687,11 +714,11 @@ if(do_mob(usr, src, STRIP_DELAY)) if(worn_id) - u_equip(worn_id) + unEquip(worn_id) usr.put_in_hands(worn_id) else if(place_item) - usr.u_equip(place_item) + usr.unEquip(place_item) equip_to_slot_if_possible(place_item, slot_wear_id, 0, 1) // Update strip window @@ -849,7 +876,7 @@ for (var/datum/data/record/R in data_core.security) if (R.fields["id"] == E.fields["id"]) if(hasHUD(usr,"security")) - var/t1 = copytext(sanitize(input("Add Comment:", "Sec. records", null, null) as message),1,MAX_MESSAGE_LEN) + var/t1 = sanitize(copytext(input("Add Comment:", "Sec. records", null, null) as message,1,MAX_MESSAGE_LEN)) if ( !(t1) || usr.stat || usr.restrained() || !(hasHUD(usr,"security")) ) return var/counter = 1 @@ -981,7 +1008,7 @@ for (var/datum/data/record/R in data_core.medical) if (R.fields["id"] == E.fields["id"]) if(hasHUD(usr,"medical")) - var/t1 = copytext(sanitize(input("Add Comment:", "Med. records", null, null) as message),1,MAX_MESSAGE_LEN) + var/t1 = sanitize(copytext(input("Add Comment:", "Med. records", null, null) as message,1,MAX_MESSAGE_LEN)) if ( !(t1) || usr.stat || usr.restrained() || !(hasHUD(usr,"medical")) ) return var/counter = 1 @@ -1036,10 +1063,10 @@ /mob/living/carbon/human/abiotic(var/full_body = 0) - if(full_body && ((src.l_hand && !( src.l_hand.abstract )) || (src.r_hand && !( src.r_hand.abstract )) || (src.back || src.wear_mask || src.head || src.shoes || src.w_uniform || src.wear_suit || src.glasses || src.l_ear || src.r_ear || src.gloves))) + if(full_body && ((src.l_hand && !(src.l_hand.flags & ABSTRACT)) || (src.r_hand && !(src.r_hand.flags & ABSTRACT)) || (src.back || src.wear_mask || src.head || src.shoes || src.w_uniform || src.wear_suit || src.glasses || src.l_ear || src.r_ear || src.gloves))) return 1 - if( (src.l_hand && !src.l_hand.abstract) || (src.r_hand && !src.r_hand.abstract) ) + if((src.l_hand && !(src.l_hand.flags & ABSTRACT)) || (src.r_hand && !(src.r_hand.flags & ABSTRACT))) return 1 return 0 @@ -1069,6 +1096,21 @@ xylophone=0 return +/mob/living/carbon/human/can_inject(var/mob/user, var/error_msg, var/target_zone) + . = 1 // Default to returning true. + if(user && !target_zone) + target_zone = user.zone_sel.selecting + // If targeting the head, see if the head item is thin enough. + // If targeting anything else, see if the wear suit is thin enough. + if(above_neck(target_zone)) + if(head && head.flags & THICKMATERIAL) + . = 0 + else + if(wear_suit && wear_suit.flags & THICKMATERIAL) + . = 0 + if(!. && error_msg && user) + // Might need re-wording. + user << "There is no exposed flesh or thin material [target_zone == "head" ? "on their head" : "on their body"]." /mob/living/carbon/human/proc/vomit(hairball=0) if(stat==2)return @@ -1159,10 +1201,15 @@ /mob/living/carbon/human/proc/is_lung_ruptured() var/datum/organ/internal/lungs/L = internal_organs_by_name["lungs"] + if(!L) + return 0 + return L.is_bruised() /mob/living/carbon/human/proc/rupture_lung() var/datum/organ/internal/lungs/L = internal_organs_by_name["lungs"] + if(!L) + return 0 if(!L.is_bruised()) src.custom_pain("You feel a stabbing pain in your chest!", 1) @@ -1293,6 +1340,7 @@ /mob/living/carbon/human/proc/set_species(var/new_species, var/force_organs, var/default_colour) + var/datum/species/oldspecies = species if(!dna) if(!new_species) new_species = "Human" @@ -1302,29 +1350,41 @@ else dna.species = new_species - if(species && (species.name && species.name == new_species)) - return + if(species) + if(species.name && species.name == new_species) + return - if(species && species.language) - remove_language(species.language) + if(species.language) + remove_language(species.language) + + if(species.default_language) + remove_language(species.default_language) species = all_species[new_species] + if(oldspecies) + if(oldspecies.default_genes.len) + oldspecies.handle_dna(src,1) // Remove any genes that belong to the old species + if(force_organs || !organs || !organs.len) species.create_organs(src) + if(vessel) + vessel = null + make_blood() + if(species.language) add_language(species.language) + if(species.default_language) + add_language(species.default_language) + see_in_dark = species.darksight if(see_in_dark > 2) see_invisible = SEE_INVISIBLE_LEVEL_ONE else see_invisible = SEE_INVISIBLE_LIVING - if(species.default_mutations.len>0 || species.default_blocks.len>0) - do_deferred_species_setup=1 - spawn(0) update_icons() @@ -1338,20 +1398,17 @@ g_skin = 0 b_skin = 0 + if(!dna) + dna = new /datum/dna(null) + dna.species = species.name + dna.real_name = real_name + dna.mutantrace = null + species.handle_post_spawn(src) spawn(0) - update_icons() - if(species && species.flags & NO_BLOOD) //We want the var for safety but we can do without the actual blood. - if(vessel.has_reagent("water") || vessel.has_reagent("blood")) - var/water = vessel.get_reagent_amount("water") - var/blood = vessel.get_reagent_amount("blood") - vessel.remove_reagent("water",water) - vessel.remove_reagent("blood",blood) - if(species.bloodflags & BLOOD_SLIME) - vessel.add_reagent("water",560-vessel.total_volume) - else - vessel.add_reagent("blood",560-vessel.total_volume) + overlays.Cut() + update_mutantrace(1) fixblood() if(species) @@ -1623,3 +1680,6 @@ /mob/living/carbon/human/canBeHandcuffed() return 1 + +/mob/living/carbon/human/InCritical() + return (health <= config.health_threshold_crit && stat == UNCONSCIOUS) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human_attackalien.dm b/code/modules/mob/living/carbon/human/human_attackalien.dm index 64d74d916de..c6e088f2c01 100644 --- a/code/modules/mob/living/carbon/human/human_attackalien.dm +++ b/code/modules/mob/living/carbon/human/human_attackalien.dm @@ -23,6 +23,7 @@ visible_message(text("\red [] has grabbed [] passively!", M, src)) if("harm") + M.do_attack_animation(src) if (w_uniform) w_uniform.add_fingerprint(M) var/damage = rand(15, 30) @@ -43,6 +44,7 @@ updatehealth() if("disarm") + M.do_attack_animation(src) var/randn = rand(1, 100) if (randn <= 80) playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1) diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index ed7c1c9336b..34f810f1c92 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -3,6 +3,10 @@ M << "No attacking people at spawn, you jackass." return + if(frozen) + M << "\red Do not touch Admin-Frozen people." + return + var/datum/organ/external/temp = M:organs_by_name["r_hand"] if (M.hand) temp = M:organs_by_name["l_hand"] @@ -14,6 +18,7 @@ if((M != src) && check_shields(0, M.name)) add_logs(src, M, "attempted to touch") + M.do_attack_animation(src) visible_message("\red [M] attempted to touch [src]!") return 0 @@ -27,7 +32,9 @@ var/datum/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting)) var/armor_block = run_armor_check(affecting, "melee") - if(M_HULK in M.mutations) damage += 5 + if(HULK in M.mutations) + damage += 5 + Weaken(4) playsound(loc, "punch", 25, 1, -1) @@ -116,6 +123,7 @@ return //end vampire codes + M.do_attack_animation(src) add_logs(src, M, "[pick(attack.attack_verb)]ed") if(!iscarbon(M)) @@ -133,8 +141,9 @@ var/datum/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting)) var/armor_block = run_armor_check(affecting, "melee") - if(M_HULK in M.mutations) damage += 5 - + if(HULK in M.mutations) + damage += 5 + Weaken(4) playsound(loc, attack.attack_sound, 25, 1, -1) @@ -176,11 +185,11 @@ if(head) var/obj/item/clothing/head/H = head if(!istype(H) || prob(H.loose)) - drop_from_inventory(H) - if(prob(60)) - step_away(H,M) - visible_message("[M] has knocked [src]'s [H] off!", - "[M] knocked \the [H] clean off your head!") */ + if(unEquip(H)) + if(prob(60)) + step_away(H,M) + visible_message("[M] has knocked [src]'s [H] off!", + "[M] knocked \the [H] clean off your head!") */ var/talked = 0 // BubbleWrap @@ -209,8 +218,8 @@ //End BubbleWrap if(!talked) //BubbleWrap - drop_item() - visible_message("\red [M] has disarmed [src]!") + if(drop_item()) + visible_message("\red [M] has disarmed [src]!") playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) return diff --git a/code/modules/mob/living/carbon/human/human_attackpaw.dm b/code/modules/mob/living/carbon/human/human_attackpaw.dm index afa59fafed6..7d2159637a6 100644 --- a/code/modules/mob/living/carbon/human/human_attackpaw.dm +++ b/code/modules/mob/living/carbon/human/human_attackpaw.dm @@ -1,17 +1,18 @@ -/mob/living/carbon/human/attack_paw(mob/M as mob) +/mob/living/carbon/human/attack_paw(mob/living/M as mob) ..() if (M.a_intent == "help") help_shake_act(M) else - if (istype(wear_mask, /obj/item/clothing/mask/muzzle)) + M.do_attack_animation(src) + if (M.is_muzzled()) return - for(var/mob/O in viewers(src, null)) - O.show_message(text("\red [M.name] has bit []!", src), 1) + visible_message("[M.name] bites [src]!", \ + "[M.name] bites [src]!") + playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) var/damage = rand(1, 3) var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg") var/datum/organ/external/affecting = get_organ(ran_zone(dam_zone)) apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, "melee")) - return diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 86c4cc95a26..a296aabd7ea 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -32,9 +32,12 @@ timeofdeath = 0 /mob/living/carbon/human/getBrainLoss() - if(species && species.flags & NO_INTORGANS) return + if(species && species.flags & NO_INTORGANS) + return var/res = brainloss var/datum/organ/internal/brain/sponge = internal_organs_by_name["brain"] + if(!sponge) + return if (sponge.is_bruised()) res += 20 if (sponge.is_broken()) @@ -107,15 +110,12 @@ hud_updateflag |= 1 << HEALTH_HUD /mob/living/carbon/human/Stun(amount) - if(M_HULK in mutations) return ..() /mob/living/carbon/human/Weaken(amount) - if(M_HULK in mutations) return ..() /mob/living/carbon/human/Paralyse(amount) - if(M_HULK in mutations) return ..() @@ -197,6 +197,7 @@ UpdateDamageIcon() hud_updateflag |= 1 << HEALTH_HUD updatehealth() + speech_problem_flag = 1 //Heal MANY external organs, in random order @@ -218,6 +219,7 @@ parts -= picked updatehealth() hud_updateflag |= 1 << HEALTH_HUD + speech_problem_flag = 1 if(update) UpdateDamageIcon() // damage MANY external organs, in random order @@ -348,7 +350,7 @@ This function restores all organs. multiplier = 2 var/obj/item/clothing/head/H = head if(!istype(H) || prob(H.loose * multiplier)) - drop_from_inventory(H) + unEquip(H) if(prob(60)) step_rand(H) if(!stat) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 96ea1ab720c..7906eac6111 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -72,7 +72,7 @@ emp_act if(c_hand && (stun_amount || agony_amount > 10)) msg_admin_attack("[src.name] ([src.ckey]) was disarmed by a stun effect") - u_equip(c_hand) + unEquip(c_hand) if (affected.status & ORGAN_ROBOT) emote("me", 1, "drops what they were holding, their [affected.display_name] malfunctioning!") else @@ -198,6 +198,16 @@ emp_act I.emp_act(severity) ..() +/mob/living/carbon/human/emag_act(user as mob, var/datum/organ/external/affecting) + if(!(affecting.status & ORGAN_ROBOT)) + user << "\red That limb isn't robotic." + return + if(affecting.sabotaged) + user << "\red [src]'s [affecting.display_name] is already sabotaged!" + else + user << "\red You sneakily slide the card into the dataport on [src]'s [affecting.display_name] and short out the safeties." + affecting.sabotaged = 1 + return 1 //Returns 1 if the attack hit, 0 if it missed. /mob/living/carbon/human/proc/attacked_by(var/obj/item/I, var/mob/living/user, var/def_zone) @@ -232,21 +242,14 @@ emp_act return 0 var/hit_area = affecting.display_name - if((user != src) && check_shields(I.force, "the [I.name]")) - return 0 + if(user != src) + user.do_attack_animation(src) + if(check_shields(I.force, "the [I.name]")) + return 0 if(istype(I,/obj/item/weapon/card/emag)) - if(!(affecting.status & ORGAN_ROBOT)) - user << "\red That limb isn't robotic." - return - if(affecting.sabotaged) - user << "\red [src]'s [affecting.display_name] is already sabotaged!" - else - user << "\red You sneakily slide [I] into the dataport on [src]'s [affecting.display_name] and short out the safeties." - var/obj/item/weapon/card/emag/emag = I - emag.uses-- - affecting.sabotaged = 1 - return 1 + emag_act(user, affecting) + if(! I.discrete) if(I.attack_verb.len) visible_message("\red [src] has been [pick(I.attack_verb)] in the [hit_area] with [I.name] by [user]!") @@ -285,8 +288,10 @@ emp_act switch(hit_area) if("head")//Harder to score a stun but if you do it lasts a bit longer if(prob(I.force)) - apply_effect(20, PARALYZE, armor) - visible_message("\red [src] has been knocked unconscious!") + apply_effect(5, WEAKEN, armor) + confused += 15 + visible_message("[src] has been knocked down!", \ + "[src] has been knocked down!") if(src != user && I.damtype == BRUTE) ticker.mode.remove_revolutionary(mind) @@ -337,6 +342,15 @@ emp_act /mob/living/carbon/human/hitby(atom/movable/AM as mob|obj,var/speed = 5) if(istype(AM,/obj/)) var/obj/O = AM + + if(in_throw_mode && !get_active_hand() && speed <= 5) //empty active hand and we're in throw mode + if(canmove && !restrained()) + if(isturf(O.loc)) + put_in_active_hand(O) + visible_message("[src] catches [O]!") + throw_mode_off() + return + var/zone = ran_zone("chest", 65) var/dtype = BRUTE if(istype(O,/obj/item/weapon)) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 6f99995aba4..4e373c7cdb8 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -50,6 +50,10 @@ var/icon/stand_icon = null var/icon/lying_icon = null + + var/voice = "" //Instead of new say code calling GetVoice() over and over and over, we're just going to ask this variable, which gets updated in Life() + + var/speech_problem_flag = 0 var/miming = null //Toggle for the mime's abilities. var/special_voice = "" // For changing our voice. Used by a symptom. @@ -71,5 +75,7 @@ var/lastFart = 0 // Toxic fart cooldown. + var/frozen = 0 //used for preventing attacks on admin-frozen people + fire_dmi = 'icons/mob/OnFire.dmi' fire_sprite = "Standing" diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 01bbfe7f5f3..64043e02bc2 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -11,7 +11,7 @@ if(embedded_flag) handle_embedded_objects() //Moving with objects stuck in you can cause bad times. - if((M_RUN in mutations)) return -1 + if((RUN in mutations)) return -1 var/health_deficiency = (100 - health + staminaloss) if(health_deficiency >= 40) @@ -55,12 +55,12 @@ tally += back.slowdown - if(M_FAT in src.mutations) + if(FAT in src.mutations) tally += 1.5 if (bodytemperature < 283.222) tally += (283.222 - bodytemperature) / 10 * 1.75 - if(M_RUN in mutations) + if(RUN in mutations) tally = 0 return (tally+config.human_delay) diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 2520b2d1982..5b7ccbf62ab 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -11,8 +11,10 @@ return if(istype(I, /obj/item/clothing/head/helmet/space/rig)) // If the item to be equipped is a rigid suit helmet - src << "\red You must fasten the helmet to a hardsuit first. (Target the head and use on a hardsuit)" // Stop eva helms equipping. - return 0 + var/obj/item/clothing/head/helmet/space/rig/C = I + if(C.rig_restrict_helmet) + src << "\red You must fasten the helmet to a hardsuit first. (Target the head and use on a hardsuit)" // Stop eva helms equipping. + return 0 if(H.equip_to_appropriate_slot(I)) if(hand) @@ -101,124 +103,98 @@ return has_organ("chest") if(slot_in_backpack) return 1 + if(slot_tie) + return 1 -/mob/living/carbon/human/u_equip(obj/item/W as obj) - if(!W) return 0 +/mob/living/carbon/human/unEquip(obj/item/I) + . = ..() //See mob.dm for an explanation on this and some rage about people copypasting instead of calling ..() like they should. + if(!. || !I) + return - var/success - if (W == wear_suit) + if(I == wear_suit) if(s_store) - drop_from_inventory(s_store) - if(W) - success = 1 + unEquip(s_store, 1) //It makes no sense for your suit storage to stay on you if you drop your suit. wear_suit = null + if(I.flags_inv & HIDEJUMPSUIT) + update_inv_w_uniform() update_inv_wear_suit() - else if (W == w_uniform) - if (r_store) - drop_from_inventory(r_store) - if (l_store) - drop_from_inventory(l_store) - if (wear_id) - drop_from_inventory(wear_id) - if (belt) - drop_from_inventory(belt) + else if(I == w_uniform) + if(r_store) + unEquip(r_store, 1) //Again, makes sense for pockets to drop. + if(l_store) + unEquip(l_store, 1) + if(wear_id) + unEquip(wear_id) + if(belt) + unEquip(belt) w_uniform = null - success = 1 update_inv_w_uniform() - else if (W == gloves) + else if(I == gloves) gloves = null - success = 1 update_inv_gloves() - else if (W == glasses) + else if(I == glasses) glasses = null - success = 1 update_inv_glasses() - else if (W == head) + else if(I == head) head = null - if((W.flags & BLOCKHAIR) || (W.flags & BLOCKHEADHAIR)) - update_hair(0) //rebuild hair - success = 1 + if(I.flags & BLOCKHAIR || I.flags & BLOCKHEADHAIR) + update_hair() //rebuild hair update_inv_head() - else if (W == l_ear) - l_ear = null - success = 1 - update_inv_ears() - else if (W == r_ear) + else if(I == r_ear) r_ear = null - success = 1 update_inv_ears() - else if (W == shoes) + else if (I == l_ear) + l_ear = null + update_inv_ears() + else if(I == shoes) shoes = null - success = 1 update_inv_shoes() - else if (W == belt) + else if(I == belt) belt = null - success = 1 update_inv_belt() - else if (W == wear_mask) + else if(I == wear_mask) wear_mask = null - success = 1 - if((W.flags & BLOCKHAIR) || (W.flags & BLOCKHEADHAIR)) - update_hair(0) //rebuild hair + if(I.flags & BLOCKHAIR || I.flags & BLOCKHEADHAIR) + update_hair() //rebuild hair if(internal) if(internals) internals.icon_state = "internal0" internal = null update_inv_wear_mask() - else if (W == wear_id) + else if(I == wear_id) wear_id = null - success = 1 update_inv_wear_id() - else if (W == wear_pda) + else if(I == wear_pda) wear_pda = null - success = 1 update_inv_wear_pda() - else if (W == r_store) + else if(I == r_store) r_store = null - success = 1 update_inv_pockets() - else if (W == l_store) + else if(I == l_store) l_store = null - success = 1 update_inv_pockets() - else if (W == s_store) + else if(I == s_store) s_store = null - success = 1 update_inv_s_store() - else if (W == back) + else if(I == back) back = null - success = 1 update_inv_back() - else if (W == handcuffed) + else if(I == handcuffed) handcuffed = null - success = 1 update_inv_handcuffed() - else if (W == legcuffed) + else if(I == legcuffed) legcuffed = null - success = 1 update_inv_legcuffed() - else if (W == r_hand) + else if(I == r_hand) r_hand = null - success = 1 update_inv_r_hand() - else if (W == l_hand) + else if(I == l_hand) l_hand = null - success = 1 update_inv_l_hand() - else - return 0 - if(success) - if (W) - if (client) - client.screen -= W - W.loc = loc - W.dropped(src) - //if(W) - //W.layer = initial(W.layer) + update_action_buttons() - return 1 @@ -335,8 +311,11 @@ update_inv_s_store(redraw_mob) if(slot_in_backpack) if(src.get_active_hand() == W) - src.u_equip(W) + src.unEquip(W) W.loc = src.back + if(slot_tie) + var/obj/item/clothing/under/uniform = src.w_uniform + uniform.attackby(W,src) else src << "You are trying to equip this item to an unsupported inventory slot. Report this to a coder!" return @@ -437,6 +416,11 @@ del(src) var/message=null + if(target.frozen) + source << "\red Do not attempt to strip frozen people." + return + + switch(place) if("syringe") message = "\red [source] is trying to inject [target]!" @@ -449,7 +433,7 @@ if("mask") target.attack_log += text("\[[time_stamp()]\] Had their mask removed by [source.name] ([source.ckey])") source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) mask") - if(target.wear_mask && !target.wear_mask.canremove) + if(target.wear_mask && (target.wear_mask.flags & NODROP)) message = "\red [source] fails to take off \a [target.wear_mask] from [target]'s head!" return else if(target.wear_mask) @@ -465,7 +449,7 @@ if("gloves") target.attack_log += text("\[[time_stamp()]\] Has had their gloves ([target.gloves]) removed by [source.name] ([source.ckey])") source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) gloves ([target.gloves])") - if(target.gloves && !target.gloves.canremove) + if(target.gloves && (target.gloves.flags & NODROP)) message = "\red [source] fails to take off \a [target.gloves] from [target]'s hands!" return else if(target.gloves) @@ -473,7 +457,7 @@ if("eyes") target.attack_log += text("\[[time_stamp()]\] Has had their eyewear ([target.glasses]) removed by [source.name] ([source.ckey])") source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) eyewear ([target.glasses])") - if(target.glasses && !target.glasses.canremove) + if(target.glasses && (target.glasses.flags & NODROP)) message = "\red [source] fails to take off \a [target.glasses] from [target]'s eyes!" return else if(target.glasses) @@ -481,7 +465,7 @@ if("l_ear") target.attack_log += text("\[[time_stamp()]\] Has had their left ear item ([target.l_ear]) removed by [source.name] ([source.ckey])") source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) left ear item ([target.l_ear])") - if(target.l_ear && !target.l_ear.canremove) + if(target.l_ear && (target.l_ear.flags & NODROP)) message = "\red [source] fails to take off \a [target.l_ear] from [target]'s left ear!" return else if(target.l_ear) @@ -489,7 +473,7 @@ if("r_ear") target.attack_log += text("\[[time_stamp()]\] Has had their right ear item ([target.r_ear]) removed by [source.name] ([source.ckey])") source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) right ear item ([target.r_ear])") - if(target.r_ear && !target.r_ear.canremove) + if(target.r_ear && (target.r_ear.flags & NODROP)) message = "\red [source] fails to take off \a [target.r_ear] from [target]'s right ear!" return else if(target.r_ear) @@ -497,7 +481,7 @@ if("head") target.attack_log += text("\[[time_stamp()]\] Has had their hat ([target.head]) removed by [source.name] ([source.ckey])") source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) hat ([target.head])") - if(target.head && !target.head.canremove) + if(target.head && (target.head.flags & NODROP)) message = "\red [source] fails to take off \a [target.head] from [target]'s head!" return else if(target.head) @@ -505,7 +489,7 @@ if("shoes") target.attack_log += text("\[[time_stamp()]\] Has had their shoes ([target.shoes]) removed by [source.name] ([source.ckey])") source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) shoes ([target.shoes])") - if(target.shoes && !target.shoes.canremove) + if(target.shoes && (target.shoes.flags & NODROP)) message = "\red [source] fails to take off \a [target.shoes] from [target]'s feet!" return else if(target.shoes) @@ -518,7 +502,7 @@ if("suit") target.attack_log += text("\[[time_stamp()]\] Has had their suit ([target.wear_suit]) removed by [source.name] ([source.ckey])") source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) suit ([target.wear_suit])") - if(target.wear_suit && !target.wear_suit.canremove) + if(target.wear_suit && (target.wear_suit.flags & NODROP)) message = "\red [source] fails to take off \a [target.wear_suit] from [target]'s body!" return else if(target.wear_suit) @@ -545,22 +529,24 @@ for(var/obj/item/I in list(target.l_store, target.r_store)) if(I.on_found(source)) return - if(target.w_uniform && !target.w_uniform.canremove) + if(target.w_uniform && (target.w_uniform.flags & NODROP)) message = "\red [source] fails to take off \a [target.w_uniform] from [target]'s body!" return else message = "\red [source] is trying to take off \a [target.w_uniform] from [target]'s body!" if("tie") var/obj/item/clothing/under/suit = target.w_uniform - target.attack_log += text("\[[time_stamp()]\] Has had their accessory ([suit.hastie]) removed by [source.name] ([source.ckey])") - source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) accessory ([suit.hastie])") - if(istype(suit.hastie, /obj/item/clothing/tie/holobadge) || istype(suit.hastie, /obj/item/clothing/tie/medal)) - for(var/mob/M in viewers(target, null)) - M.show_message("\red [source] tears off \the [suit.hastie] from [target]'s suit!" , 1) - done() - return - else - message = "\red [source] is trying to take off \a [suit.hastie] from [target]'s suit!" + if(suit.accessories.len) + var/obj/item/clothing/accessory/A = suit.accessories[1] + target.attack_log += "\[[time_stamp()]\] Has had their accessory ([A]) removed by [source.name] ([source.ckey])" + source.attack_log += "\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) accessory ([A])" + if(istype(A, /obj/item/clothing/accessory/holobadge) || istype(A, /obj/item/clothing/accessory/medal)) + for(var/mob/M in viewers(target, null)) + M.show_message("\red [source] tears off \the [A] from [target]'s [suit]!" , 1) + done() + return + else + message = "\red [source] is trying to take off \a [A] from [target]'s [suit]!" if("s_store") target.attack_log += text("\[[time_stamp()]\] Has had their suit storage item ([target.s_store]) removed by [source.name] ([source.ckey])") source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) suit storage item ([target.s_store])") @@ -626,7 +612,7 @@ It works in conjuction with the process() above. This proc works for humans only. Aliens stripping humans and the like will all use this proc. Stripping monkeys or somesuch will use their version of this proc. The first if statement for "mask" and such refers to items that are already equipped and un-equipping them. The else statement is for equipping stuff to empty slots. -!canremove refers to variable of /obj/item/clothing which either allows or disallows that item to be removed. +The NODROP flag refers to variable of /obj/item/clothing which either allows or disallows that item to be removed. It can still be worn/put on as normal. */ /obj/effect/equip_e/human/done() //TODO: And rewrite this :< ~Carn @@ -638,6 +624,10 @@ It can still be worn/put on as normal. if (LinkBlockedUnclimbable(t_loc, s_loc)) return if(item && source.get_active_hand() != item) return //Swapped hands / removed item from the active one if ((source.restrained() || source.stat)) return //Source restrained or unconscious / dead + if(target.frozen) + source << "\red Do not attempt to strip frozen people." + return + var/slot_to_process var/strip_item //this will tell us which item we will be stripping - if any. @@ -645,11 +635,11 @@ It can still be worn/put on as normal. switch(place) //here we go again... if("mask") slot_to_process = slot_wear_mask - if (target.wear_mask && target.wear_mask.canremove) + if (target.wear_mask && !(target.wear_mask.flags & NODROP)) strip_item = target.wear_mask if("gloves") slot_to_process = slot_gloves - if (target.gloves && target.gloves.canremove) + if (target.gloves && !(target.gloves.flags & NODROP)) strip_item = target.gloves if("eyes") slot_to_process = slot_glasses @@ -665,7 +655,7 @@ It can still be worn/put on as normal. strip_item = target.s_store if("head") slot_to_process = slot_head - if (target.head && target.head.canremove) + if (target.head && !(target.head.flags & NODROP)) strip_item = target.head if("l_ear") slot_to_process = slot_l_ear @@ -677,7 +667,7 @@ It can still be worn/put on as normal. strip_item = target.r_ear if("shoes") slot_to_process = slot_shoes - if (target.shoes && target.shoes.canremove) + if (target.shoes && !(target.shoes.flags & NODROP)) strip_item = target.shoes if("l_hand") if (istype(target, /obj/item/clothing/suit/straight_jacket)) @@ -693,23 +683,27 @@ It can still be worn/put on as normal. strip_item = target.r_hand if("uniform") slot_to_process = slot_w_uniform - if(target.w_uniform && target.w_uniform.canremove) + if(target.w_uniform && !(target.w_uniform.flags & NODROP)) strip_item = target.w_uniform if("suit") slot_to_process = slot_wear_suit - if (target.wear_suit && target.wear_suit.canremove) + if (target.wear_suit && !(target.wear_suit.flags & NODROP)) strip_item = target.wear_suit if("tie") var/obj/item/clothing/under/suit = target.w_uniform - var/obj/item/clothing/tie/tie = suit.hastie - if(tie) - if (istype(tie,/obj/item/clothing/tie/storage)) - var/obj/item/clothing/tie/storage/W = tie + //var/obj/item/clothing/accessory/tie = suit.hastie + /*if(tie) + if (istype(tie,/obj/item/clothing/accessory/storage)) + var/obj/item/clothing/accessory/storage/W = tie if (W.hold) W.hold.close(usr) usr.put_in_hands(tie) - suit.hastie = null - target.update_inv_w_uniform() + suit.hastie = null*/ + if(suit && suit.accessories.len) + var/obj/item/clothing/accessory/A = suit.accessories[1] + A.on_removed(usr) + suit.accessories -= A + target.update_inv_w_uniform() if("id") slot_to_process = slot_wear_id if (target.wear_id) @@ -741,7 +735,7 @@ It can still be worn/put on as normal. W.layer = initial(W.layer) W.add_fingerprint(source) if("CPR") - if ((target.health > config.health_threshold_dead && target.health < config.health_threshold_crit)) + if ((target.health > config.health_threshold_dead && target.health <= config.health_threshold_crit)) var/suff = min(target.getOxyLoss(), 7) target.adjustOxyLoss(-suff) target.updatehealth() @@ -799,7 +793,9 @@ It can still be worn/put on as normal. if(slot_to_process) if(strip_item) //Stripping an item from the mob var/obj/item/W = strip_item - target.u_equip(W) + if((W.flags & NODROP) || (W.flags & ABSTRACT)) //Just to be sure + return + target.unEquip(W) if (target.client) target.client.screen -= W if (W) @@ -809,11 +805,11 @@ It can still be worn/put on as normal. W.add_fingerprint(source) if(slot_to_process == slot_l_store) //pockets! Needs to process the other one too. Snowflake code, wooo! It's not like anyone will rewrite this anytime soon. If I'm wrong then... CONGRATULATIONS! ;) if(target.r_store) - target.u_equip(target.r_store) //At this stage l_store is already processed by the code above, we only need to process r_store. + target.unEquip(target.r_store) //At this stage l_store is already processed by the code above, we only need to process r_store. else if(item && target.has_organ_for_slot(slot_to_process)) //Placing an item on the mob if(item.mob_can_equip(target, slot_to_process, 0)) - source.u_equip(item) + source.unEquip(item) target.equip_to_slot_if_possible(item, slot_to_process, 0, 1, 1) item.dropped(source) source.update_icons() @@ -833,7 +829,7 @@ It can still be worn/put on as normal. return r_hand return null -/mob/living/carbon/human/get_item_by_slot(slot_id) +/mob/living/carbon/get_item_by_slot(slot_id) switch(slot_id) if(slot_back) return back @@ -849,4 +845,45 @@ It can still be worn/put on as normal. return r_hand return null - +// Return the item currently in the slot ID +/mob/living/carbon/human/get_item_by_slot(slot_id) + switch(slot_id) + if(slot_back) + return back + if(slot_wear_mask) + return wear_mask + if(slot_handcuffed) + return handcuffed + if(slot_legcuffed) + return legcuffed + if(slot_l_hand) + return l_hand + if(slot_r_hand) + return r_hand + if(slot_belt) + return belt + if(slot_wear_id) + return wear_id + if(slot_l_ear) + return l_ear + if(slot_r_ear) + return r_ear + if(slot_glasses) + return glasses + if(slot_gloves) + return gloves + if(slot_head) + return head + if(slot_shoes) + return shoes + if(slot_wear_suit) + return wear_suit + if(slot_w_uniform) + return w_uniform + if(slot_l_store) + return l_store + if(slot_r_store) + return r_store + if(slot_s_store) + return s_store + return null diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 8eb38c1e7b0..6c2c876ef50 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -33,27 +33,9 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc var/prev_gender = null // Debug for plural genders var/temperature_alert = 0 var/in_stasis = 0 - var/do_deferred_species_setup=0 var/exposedtimenow = 0 var/firstexposed = 0 -// Doing this during species init breaks shit. -/mob/living/carbon/human/proc/DeferredSpeciesSetup() - var/mut_update=0 - if(species.default_mutations.len>0) - for(var/mutation in species.default_mutations) - if(!(mutation in mutations)) - mutations.Add(mutation) - mut_update=1 - if(species.default_blocks.len>0) - for(var/block in species.default_blocks) - if(!dna.GetSEState(block)) - dna.SetSEState(block,1) - mut_update=1 - if(mut_update) - domutcheck(src,null,MUTCHK_FORCED) - update_mutations() - /mob/living/carbon/human/Life() set invisibility = 0 //set background = 1 @@ -63,10 +45,6 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc ..() - if(do_deferred_species_setup) - DeferredSpeciesSetup() - do_deferred_species_setup=0 - //Apparently, the person who wrote this code designed it so that //blinded get reset each cycle and then get activated later in the //code. Very ugly. I dont care. Moving this stuff here so its easy @@ -85,6 +63,8 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc if(life_tick%30==15) hud_updateflag = 1022 + voice = GetVoice() + //No need to update all of these procs if the guy is dead. if(stat != DEAD && !in_stasis) if(air_master.current_cycle%4==2 || failed_last_breath) //First, resolve location and get a breath @@ -252,22 +232,26 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc drop_item() emote("cough") if (disabilities & TOURETTES) + speech_problem_flag = 1 if ((prob(10) && paralysis <= 1)) Stun(10) switch(rand(1, 3)) if(1) emote("twitch") if(2 to 3) - say("[prob(50) ? ";" : ""][pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER", "TITS")]") + var/tourettes = pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER", "TITS") + say("[prob(50) ? ";" : ""][tourettes]") var/x_offset = pixel_x + rand(-2,2) //Should probably be moved into the twitch emote at some point. var/y_offset = pixel_y + rand(-1,1) animate(src, pixel_x = pixel_x + x_offset, pixel_y = pixel_y + y_offset, time = 1) - animate(pixel_x = pixel_x - x_offset, pixel_y = pixel_y - y_offset, time = 1) + animate(pixel_x = initial(pixel_x) , pixel_y = initial(pixel_y), time = 1) if (disabilities & NERVOUS) + speech_problem_flag = 1 if (prob(10)) stuttering = max(10, stuttering) if (getBrainLoss() >= 60 && stat != 2) + speech_problem_flag = 1 if (prob(3)) switch(pick(1,2,3)) if(1) @@ -319,7 +303,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc return if(getFireLoss()) - if((M_RESIST_HEAT in mutations) || (prob(1))) + if((RESIST_HEAT in mutations) || (prob(1))) heal_organ_damage(0,1) @@ -329,6 +313,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc if(gene.is_active(src)) /* if (prob(10) && prob(gene.instability)) adjustCloneLoss(1) */ + speech_problem_flag = 1 gene.OnMobLife(src) if (radiation) @@ -404,7 +389,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc proc/breathe() if(reagents.has_reagent("lexorin")) return - if(M_NO_BREATH in mutations) return // No breath mutation means no breathing. + if(NO_BREATH in mutations) return // No breath mutation means no breathing. if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return if(species && (species.flags & NO_BREATHE)) return @@ -412,7 +397,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc var/datum/gas_mixture/breath // HACK NEED CHANGING LATER - if(health < config.health_threshold_crit) + if(health <= config.health_threshold_crit) losebreath++ if(losebreath>0) //Suffocating so do not take a breath @@ -481,7 +466,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc if(species.name=="Plasmaman") // Check if we're wearing our biosuit and mask. - if (!istype(wear_suit,/obj/item/clothing/suit/space/plasmaman) || !istype(head,/obj/item/clothing/head/helmet/space/plasmaman)) + if (!istype(wear_suit,/obj/item/clothing/suit/space/eva/plasmaman) || !istype(head,/obj/item/clothing/head/helmet/space/eva/plasmaman)) //testing("Plasmaman [src] leakin'. coverflags=[cover_flags]") // OH FUCK HE LEAKIN'. // This was OP. @@ -591,32 +576,34 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc //Body temperature is too hot. fire_alert = max(fire_alert, 1) if(status_flags & GODMODE) return 1 //godmode - switch(bodytemperature) - if(species.heat_level_1 to species.heat_level_2) - take_overall_damage(burn=HEAT_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature") + if(bodytemperature >= species.heat_level_1 && bodytemperature <= species.heat_level_2) + take_overall_damage(burn=HEAT_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature") + fire_alert = max(fire_alert, 2) + if(bodytemperature > species.heat_level_2 && bodytemperature <= species.heat_level_3) + take_overall_damage(burn=HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature") + fire_alert = max(fire_alert, 2) + if(bodytemperature > species.heat_level_3 && bodytemperature < INFINITY) + if(on_fire) + take_overall_damage(burn=HEAT_DAMAGE_LEVEL_3, used_weapon = "Fire") fire_alert = max(fire_alert, 2) - if(species.heat_level_2 to species.heat_level_3) + else take_overall_damage(burn=HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature") fire_alert = max(fire_alert, 2) - if(species.heat_level_3 to INFINITY) - take_overall_damage(burn=HEAT_DAMAGE_LEVEL_3, used_weapon = "High Body Temperature") - fire_alert = max(fire_alert, 2) else if(bodytemperature < species.cold_level_1) fire_alert = max(fire_alert, 1) if(status_flags & GODMODE) return 1 //godmode if(stat == DEAD) return 1 //ZomgPonies -- No need for cold burn damage if dead if(!istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) - switch(bodytemperature) - if(species.cold_level_2 to species.cold_level_1) - take_overall_damage(burn=COLD_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature") - fire_alert = max(fire_alert, 1) - if(species.cold_level_3 to species.cold_level_2) - take_overall_damage(burn=COLD_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature") - fire_alert = max(fire_alert, 1) - if(-INFINITY to species.cold_level_3) - take_overall_damage(burn=COLD_DAMAGE_LEVEL_3, used_weapon = "High Body Temperature") - fire_alert = max(fire_alert, 1) + if(bodytemperature >= species.cold_level_2 && bodytemperature <= species.cold_level_1) + take_overall_damage(burn=COLD_DAMAGE_LEVEL_1, used_weapon = "Low Body Temperature") + fire_alert = max(fire_alert, 1) + if(bodytemperature >= species.cold_level_3 && bodytemperature < species.cold_level_2) + take_overall_damage(burn=COLD_DAMAGE_LEVEL_2, used_weapon = "Low Body Temperature") + fire_alert = max(fire_alert, 1) + if(bodytemperature > -INFINITY && bodytemperature < species.cold_level_3) + take_overall_damage(burn=COLD_DAMAGE_LEVEL_3, used_weapon = "Low Body Temperature") + fire_alert = max(fire_alert, 1) // Account for massive pressure differences. Done by Polymorph // Made it possible to actually have something that can protect against high pressure... Done by Errorage. Polymorph now has an axe sticking from his head for his previous hardcoded nonsense! @@ -633,7 +620,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc else if(adjusted_pressure >= species.hazard_low_pressure) pressure_alert = -1 else - if( !(M_RESIST_COLD in mutations)) + if( !(RESIST_COLD in mutations)) take_overall_damage(brute=LOW_PRESSURE_DAMAGE, used_weapon = "Low Pressure") pressure_alert = -2 else @@ -647,8 +634,20 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc handle_fire() if(..()) return - var/thermal_protection = get_heat_protection(10000) //If you don't have fire suit level protection, you get a temperature increase - if((1 - thermal_protection) > 0.0001) + var/thermal_protection = 0 //Simple check to estimate how protected we are against multiple temperatures + if(wear_suit) + if(wear_suit.max_heat_protection_temperature >= FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE) + thermal_protection += (wear_suit.max_heat_protection_temperature*0.7) + if(head) + if(head.max_heat_protection_temperature >= FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE) + thermal_protection += (head.max_heat_protection_temperature*THERMAL_PROTECTION_HEAD) + thermal_protection = round(thermal_protection) + if(thermal_protection >= FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT) + return + if(thermal_protection >= FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE) + bodytemperature += 11 + return + else bodytemperature += BODYTEMP_HEATING_MAX return //END FIRE CODE @@ -735,7 +734,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc var/thermal_protection_flags = get_heat_protection_flags(temperature) var/thermal_protection = 0.0 - if(M_RESIST_HEAT in mutations) + if(RESIST_HEAT in mutations) return 1 if(thermal_protection_flags) if(thermal_protection_flags & HEAD) @@ -792,7 +791,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc proc/get_cold_protection(temperature) - if(M_RESIST_COLD in mutations) + if(RESIST_COLD in mutations) return 1 //Fully protected from the cold. temperature = max(temperature, 2.7) //There is an occasional bug where the temperature is miscalculated in ares with a small amount of gas on them, so this is necessary to ensure that that bug does not affect this calculation. Space's temperature is 2.7K and most suits that are intended to protect against any cold, protect down to 2.0K. @@ -929,10 +928,12 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc traumatic_shock -= light_amount if(species.flags & IS_PLANT) - if(nutrition > 500) - nutrition = 500 + if(nutrition > 450) + nutrition = 450 if(light_amount >= 5) //if there's enough light, heal - adjustBruteLoss(-(light_amount)) + adjustBruteLoss(-(light_amount/2)) + adjustFireLoss(-(light_amount/4)) + //adjustToxLoss(-(light_amount)) adjustOxyLoss(-(light_amount)) //TODO: heal wounds, heal broken limbs. @@ -949,12 +950,12 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc else if (light_amount < 2) //heal in the dark heal_overall_damage(1,1) - //The fucking M_FAT mutation is the greatest shit ever. It makes everyone so hot and bothered. + //The fucking FAT mutation is the greatest shit ever. It makes everyone so hot and bothered. if(species.flags & CAN_BE_FAT) - if(M_FAT in mutations) + if(FAT in mutations) if(overeatduration < 100) src << "\blue You feel fit again!" - mutations.Remove(M_FAT) + mutations.Remove(FAT) update_mutantrace(0) update_mutations(0) update_inv_w_uniform(0) @@ -962,7 +963,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc else if(overeatduration > 500) src << "\red You suddenly feel blubbery!" - mutations.Add(M_FAT) + mutations.Add(FAT) update_mutantrace(0) update_mutations(0) update_inv_w_uniform(0) @@ -978,7 +979,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc else if(overeatduration > 1) - if(M_OBESITY in mutations) + if(OBESITY in mutations) overeatduration -= 1 // Those with obesity gene take twice as long to unfat else overeatduration -= 2 @@ -1021,7 +1022,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc silent = 0 else //ALIVE. LIGHTS ARE ON - if(M_REGEN in mutations) + if(REGEN in mutations) if(nutrition) if(prob(10)) var/randumb = rand(1,5) @@ -1032,7 +1033,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc // Sobering multiplier. // Sober block grants quadruple the alcohol metabolism. -// var/sober_str=!(M_SOBER in mutations)?1:4 +// var/sober_str=!(SOBER in mutations)?1:4 updatehealth() //TODO if(!in_stasis) @@ -1050,7 +1051,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc analgesic = max(0, analgesic - 1) //UNCONSCIOUS. NO-ONE IS HOME - if( (getOxyLoss() > 50) || (config.health_threshold_crit > health) ) + if( (getOxyLoss() > 50) || (config.health_threshold_crit >= health) ) Paralyse(3) /* Done by handle_breath() @@ -1061,11 +1062,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc adjustOxyLoss(1)*/ if(hallucination && !(species.flags & IS_SYNTHETIC)) - if(hallucination >= 20) - if(prob(3)) - fake_attack(src) - if(!handling_hal) - spawn handle_hallucinations() //The not boring kind! + spawn handle_hallucinations() if(hallucination<=2) hallucination = 0 @@ -1091,6 +1088,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc if(halloss > 0) adjustHalLoss(-3) else if(sleeping) + speech_problem_flag = 1 handle_dreams() adjustStaminaLoss(-10) adjustHalLoss(-3) @@ -1183,13 +1181,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc //Jitteryness if(jitteriness) - var/amplitude = min(4, (jitteriness/100) + 1) - var/pixel_x_diff = rand(-amplitude, amplitude) - var/pixel_y_diff = rand(-amplitude/3, amplitude/3) - - animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff , time = 2, loop = 6) - animate(pixel_x = pixel_x - pixel_x_diff, pixel_y = pixel_y - pixel_y_diff, time = 2) - jitteriness = max(jitteriness-1, 0) + do_jitter_animation(jitteriness) //Other handle_statuses() @@ -1312,7 +1304,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS see_in_dark = 8 if(!druggy) see_invisible = SEE_INVISIBLE_LEVEL_TWO - if(M_XRAY in mutations) + if(XRAY in mutations) sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS see_in_dark = 8 if(!druggy) see_invisible = SEE_INVISIBLE_LEVEL_TWO @@ -1523,7 +1515,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc if(!machine.check_eye(src)) reset_view(null) else var/isRemoteObserve = 0 - if((M_REMOTE_VIEW in mutations) && remoteview_target) + if((REMOTE_VIEW in mutations) && remoteview_target) isRemoteObserve = 1 // Is he unconscious or dead? if(remoteview_target.stat!=CONSCIOUS) @@ -1531,13 +1523,13 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc isRemoteObserve = 0 // Does he have psy resist? - if(M_PSY_RESIST in remoteview_target.mutations) + if(PSY_RESIST in remoteview_target.mutations) src << "\red Your mind is shut out!" isRemoteObserve = 0 // Not on the station or mining? var/turf/temp_turf = get_turf(remoteview_target) - if((temp_turf.z != 1 && temp_turf.z != 5) || remoteview_target.stat!=CONSCIOUS) + if((!(temp_turf.z in config.contact_levels)) || remoteview_target.stat!=CONSCIOUS) src << "\red Your psy-connection grows too faint to maintain!" isRemoteObserve = 0 if(!isRemoteObserve && client && !client.adminobs) @@ -1646,7 +1638,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc if(status_flags & GODMODE) return 0 //godmode if(analgesic || (species && species.flags & NO_PAIN)) return // analgesic avoids all traumatic shock temporarily - if(health < 0)// health 0 makes you immediately collapse + if(health <= config.health_threshold_softcrit)// health 0 makes you immediately collapse shock_stage = max(shock_stage, 61) if(traumatic_shock >= 100) @@ -1945,6 +1937,28 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc for(var/mob/living/carbon/human/H in view(src, 14)) C.images += H.hud_list[NATIONS_HUD] +/mob/living/carbon/human/handle_silent() + if(..()) + speech_problem_flag = 1 + return silent + +/mob/living/carbon/human/handle_slurring() + if(..()) + speech_problem_flag = 1 + return slurring + +/mob/living/carbon/human/handle_stunned() + if(species.flags & NO_PAIN) + stunned = 0 + return 0 + if(..()) + speech_problem_flag = 1 + return stunned + +/mob/living/carbon/human/handle_stuttering() + if(..()) + speech_problem_flag = 1 + return stuttering // Need this in species. //#undef HUMAN_MAX_OXYLOSS diff --git a/code/modules/mob/living/carbon/human/plasmaman/species.dm b/code/modules/mob/living/carbon/human/plasmaman/species.dm index d940b638373..29e54e8ab8f 100644 --- a/code/modules/mob/living/carbon/human/plasmaman/species.dm +++ b/code/modules/mob/living/carbon/human/plasmaman/species.dm @@ -24,32 +24,54 @@ H.fire_sprite = "Plasmaman" // Unequip existing suits and hats. - H.u_equip(H.wear_suit) - H.u_equip(H.head) + H.unEquip(H.wear_suit) + H.unEquip(H.head) if(H.mind.assigned_role!="Clown") - H.u_equip(H.wear_mask) + H.unEquip(H.wear_mask) H.equip_or_collect(new /obj/item/clothing/mask/breath(H), slot_wear_mask) - var/suit=/obj/item/clothing/suit/space/plasmaman - var/helm=/obj/item/clothing/head/helmet/space/plasmaman + var/suit=/obj/item/clothing/suit/space/eva/plasmaman + var/helm=/obj/item/clothing/head/helmet/space/eva/plasmaman var/tank_slot = slot_s_store var/tank_slot_name = "suit storage" switch(H.mind.assigned_role) - /* if("Research Director","Scientist","Geneticist","Roboticist") - suit=/obj/item/clothing/suit/space/vox/casual/science - helm=/obj/item/clothing/head/helmet/space/vox/casual/science - if("Chief Engineer","Station Engineer","Atmospheric Technician") - suit=/obj/item/clothing/suit/space/vox/casual/engineer - helm=/obj/item/clothing/head/helmet/space/vox/casual/engineer + suit=/obj/item/clothing/suit/space/eva/plasmaman/science + helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/science + if("Chief Engineer","Station Engineer") + suit=/obj/item/clothing/suit/space/eva/plasmaman/engineer + helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/engineer + if("Atmospheric Technician") + suit=/obj/item/clothing/suit/space/eva/plasmaman/atmostech + helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/atmostech if("Head of Security","Warden","Detective","Security Officer") - suit=/obj/item/clothing/suit/space/vox/casual/security - helm=/obj/item/clothing/head/helmet/space/vox/casual/security + suit=/obj/item/clothing/suit/space/eva/plasmaman/security + helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security if("Chief Medical Officer","Medical Doctor","Paramedic","Chemist") - suit=/obj/item/clothing/suit/space/vox/casual/medical - helm=/obj/item/clothing/head/helmet/space/vox/casual/medical - */ // For now. + suit=/obj/item/clothing/suit/space/eva/plasmaman/medical + helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/medical + if("Bartender", "Chef") + suit=/obj/item/clothing/suit/space/eva/plasmaman/service + helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/service + if("Cargo Technician", "Quartermaster") + suit=/obj/item/clothing/suit/space/eva/plasmaman/cargo + helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/cargo + if("Shaft Miner") + suit=/obj/item/clothing/suit/space/eva/plasmaman/miner + helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/miner + if("Botanist") + suit=/obj/item/clothing/suit/space/eva/plasmaman/botanist + helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/botanist + if("Chaplain") + suit=/obj/item/clothing/suit/space/eva/plasmaman/chaplain + helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/chaplain + if("Janitor") + suit=/obj/item/clothing/suit/space/eva/plasmaman/janitor + helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/janitor + if("Assistant") + suit=/obj/item/clothing/suit/space/eva/plasmaman/assistant + helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/assistant if("Clown","Mime") tank_slot=slot_r_hand tank_slot_name = "hand" @@ -130,7 +152,7 @@ H.emote(pick("giggle", "laugh")) SA.moles = 0 - if( (abs(310.15 - breath.temperature) > 50) && !(M_RESIST_HEAT in H.mutations)) // Hot air hurts :( + if( (abs(310.15 - breath.temperature) > 50) && !(RESIST_HEAT in H.mutations)) // Hot air hurts :( if(H.status_flags & GODMODE) return 1 //godmode if(breath.temperature < cold_level_1) diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index 028f0efe755..1eda618789a 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -1,81 +1,152 @@ /mob/living/carbon/human/say(var/message) - if(miming) - if(length(message) >= 2) - if(mind && mind.changeling) - if(copytext(message, 1, 2) != "*" && department_radio_keys[copytext(message, 1, 3)] != "changeling") - return - else - return ..(message) - if(stat == DEAD) - return ..(message) - if(length(message) >= 1) //In case people forget the '*help' command, this will slow them the message and prevent people from saying one letter at a time - if (copytext(message, 1, 2) != "*") - return + var/verb = "says" + var/alt_name = "" + var/message_range = world.view + var/italics = 0 - if(dna) - if(length(message) >= 2) - if (copytext(message, 1, 2) != "*" && department_radio_keys[copytext(message, 1, 3)] != "changeling") - for(var/datum/dna/gene/gene in dna_genes) - if(!gene.block) - continue - if(gene.is_active(src)) - message = gene.OnSay(src,message) - /* - if(dna.mutantrace == "lizard") - if(copytext(message, 1, 2) != "*") - message = replacetext(message, "s", stutter("ss")) + if(client) + if(client.prefs.muted & MUTE_IC) + src << "\red You cannot speak in IC (Muted)." + return - if(dna.mutantrace == "slime" && prob(5)) - if(copytext(message, 1, 2) != "*") - if(copytext(message, 1, 2) == ";") - message = ";" - else - message = "" - message += "SKR" - var/imax = rand(5,20) - for(var/i = 0,iYou're muzzled and cannot speak!
" + return + + var/message_mode = parse_message_mode(message, "headset") + + if(copytext(message,1,2) == "*") + return emote(copytext(message,2)) + + if(name != GetVoice()) + alt_name = "(as [get_id_name("Unknown")])" + + //parse the radio code and consume it + if (message_mode) + if (message_mode == "headset") + message = copytext(message,2) //it would be really nice if the parse procs could do this for us. + else + message = copytext(message,3) + + //parse the language code and consume it + var/datum/language/speaking = parse_language(message) + if(speaking) + message = copytext(message,2+length(speaking.key)) + else if(species.default_language) + speaking = all_languages[species.default_language] + + var/ending = copytext(message, length(message)) + if (speaking) + // This is broadcast to all mobs with the language, + // irrespective of distance or anything else. + if(speaking.flags & HIVEMIND) + speaking.broadcast(src,trim(message)) + return + //If we've gotten this far, keep going! + verb = speaking.get_spoken_verb(ending) + else + if(ending=="!") + verb=pick("exclaims","shouts","yells") + if(ending=="?") + verb="asks" + + message = trim(message) + + if(speech_problem_flag) + var/list/handle_r = handle_speech_problems(message) + message = handle_r[1] + verb = handle_r[2] + speech_problem_flag = handle_r[3] + + if(!message || message == "") + return + + var/list/obj/item/used_radios = new + + switch (message_mode) + if("headset") + if(l_ear && istype(l_ear,/obj/item/device/radio)) + var/obj/item/device/radio/R = l_ear + R.talk_into(src,message,null,verb,speaking) + used_radios += l_ear + else if(r_ear && istype(r_ear,/obj/item/device/radio)) + var/obj/item/device/radio/R = r_ear + R.talk_into(src,message,null,verb,speaking) + used_radios += r_ear + + if("right ear") + var/obj/item/device/radio/R + var/has_radio = 0 + if(r_ear && istype(r_ear,/obj/item/device/radio)) + R = r_ear + has_radio = 1 + if(r_hand && istype(r_hand, /obj/item/device/radio)) + R = r_hand + has_radio = 1 + if(has_radio) + R.talk_into(src,message,null,verb,speaking) + used_radios += R - if(wear_mask) - if(istype(wear_mask, /obj/item/clothing/mask/gas/voice/space_ninja) && wear_mask:voice == "Unknown") - if(copytext(message, 1, 2) != "*") - var/list/temp_message = text2list(message, " ") - var/list/pick_list = list() - for(var/i = 1, i <= temp_message.len, i++) - pick_list += i - for(var/i=1, i <= abs(temp_message.len/3), i++) - var/H = pick(pick_list) - if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue - temp_message[H] = ninjaspeak(temp_message[H]) - pick_list -= H - message = list2text(temp_message, " ") - message = replacetext(message, "o", "¤") - message = replacetext(message, "p", "þ") - message = replacetext(message, "l", "£") - message = replacetext(message, "s", "§") - message = replacetext(message, "u", "µ") - message = replacetext(message, "b", "ß") + if("left ear") + var/obj/item/device/radio/R + var/has_radio = 0 + if(l_ear && istype(l_ear,/obj/item/device/radio)) + R = l_ear + has_radio = 1 + if(l_hand && istype(l_hand,/obj/item/device/radio)) + R = l_hand + has_radio = 1 + if(has_radio) + R.talk_into(src,message,null,verb,speaking) + used_radios += R - else if(istype(wear_mask, /obj/item/clothing/mask/horsehead)) - var/obj/item/clothing/mask/horsehead/hoers = wear_mask - if(hoers.voicechange) - if(!(copytext(message, 1, 2) == "*" || (mind && mind.changeling && department_radio_keys[copytext(message, 1, 3)] != "changeling"))) - message = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!") + if("intercom") + for(var/obj/item/device/radio/intercom/I in view(1, null)) + I.talk_into(src, message, verb, speaking) + used_radios += I + if("whisper") + whisper_say(message, speaking, alt_name) + return + else + if(message_mode) + if(l_ear && istype(l_ear,/obj/item/device/radio)) + l_ear.talk_into(src,message, message_mode, verb, speaking) + used_radios += l_ear + else if(r_ear && istype(r_ear,/obj/item/device/radio)) + r_ear.talk_into(src,message, message_mode, verb, speaking) + used_radios += r_ear - if ((M_HULK in mutations) && health >= 25 && length(message)) - if(copytext(message, 1, 2) != "*") - message = "[uppertext(message)]!!" //because I don't know how to code properly in getting vars from other files -Bro + var/sound/speech_sound + var/sound_vol + if(species.speech_sounds && prob(species.speech_chance)) + speech_sound = sound(pick(species.speech_sounds)) + sound_vol = 50 - if (src.slurring) - if(copytext(message, 1, 2) != "*") - message = slur(message) + //speaking into radios + if(used_radios.len) + italics = 1 + message_range = 1 + if(speaking) + message_range = speaking.get_talkinto_msg_range(message) + var/msg + if(!speaking || !(speaking.flags & NO_TALK_MSG)) + msg = "\The [src] talks into \the [used_radios[1]]" + for(var/mob/living/M in hearers(5, src)) + if((M != src) && msg) + M.show_message(msg) + if (speech_sound) + sound_vol *= 0.5 - if((species.name == "Vox" || species.name == "Vox Armalis") && prob(20)) - playsound(src.loc, 'sound/voice/shriek1.ogg', 50, 1) - - ..(message) + ..(message, speaking, verb, alt_name, italics, message_range, speech_sound, sound_vol) //ohgod we should really be passing a datum here. /mob/living/carbon/human/proc/forcesay(list/append) if(stat == CONSCIOUS) @@ -100,6 +171,7 @@ if(findtext(temp, "*", 1, 2)) //emotes return temp = copytext(trim_left(temp), 1, rand(5,8)) + var/trimmed = trim_left(temp) if(length(trimmed)) if(append) @@ -108,25 +180,45 @@ say(temp) winset(client, "input", "text=[null]") -/mob/living/carbon/human/say_understands(var/other,var/datum/language/speaking = null) +/mob/living/carbon/human/say_understands(var/mob/other,var/datum/language/speaking = null) if(has_brain_worms()) //Brain worms translate everything. Even mice and alien speak. return 1 - if (istype(other, /mob/living/silicon)) - return 1 - if (istype(other, /mob/living/carbon/brain)) - return 1 - if (istype(other, /mob/living/carbon/slime)) + + if(species.can_understand(other)) return 1 + + //These only pertain to common. Languages are handled by mob/say_understands() + if (!speaking) + if (istype(other, /mob/living/carbon/monkey/diona)) + if(other.languages.len >= 2) //They've sucked down some blood and can speak common now. + return 1 + if (istype(other, /mob/living/silicon)) + return 1 + if (istype(other, /mob/living/carbon/brain)) + return 1 + if (istype(other, /mob/living/carbon/slime)) + return 1 + + //This is already covered by mob/say_understands() + //if (istype(other, /mob/living/simple_animal)) + // if((other.universal_speak && !speaking) || src.universal_speak || src.universal_understand) + // return 1 + // return 0 + return ..() /mob/living/carbon/human/GetVoice() - if(istype(src.wear_mask, /obj/item/clothing/mask/gas/voice)) - var/obj/item/clothing/mask/gas/voice/V = src.wear_mask - if(V.vchange) - return V.voice - else - return name + + var/voice_sub + for(var/obj/item/gear in list(wear_mask,wear_suit,head)) + if(!gear) + continue + var/obj/item/voice_changer/changer = locate() in gear + if(changer && changer.active && changer.voice) + voice_sub = changer.voice + if(voice_sub) + return voice_sub if(mind && mind.changeling && mind.changeling.mimicing) return mind.changeling.mimicing if(GetSpecialVoice()) @@ -143,4 +235,83 @@ return /mob/living/carbon/human/proc/GetSpecialVoice() - return special_voice \ No newline at end of file + return special_voice + + +/* + ***Deprecated*** + let this be handled at the hear_say or hear_radio proc + This is left in for robot speaking when humans gain binary channel access until I get around to rewriting + robot_talk() proc. + There is no language handling build into it however there is at the /mob level so we accept the call + for it but just ignore it. +*/ + +/mob/living/carbon/human/say_quote(var/message, var/datum/language/speaking = null) + var/verb = "says" + var/ending = copytext(message, length(message)) + + if(speaking) + verb = speaking.get_spoken_verb(ending) + else + if(ending == "!") + verb = "exclaims" + else if(ending == "?") + verb = "asks" + + return verb + +/mob/living/carbon/human/proc/handle_speech_problems(var/message) + + var/list/returns[3] + var/verb = "says" + var/handled = 0 + if(silent || (sdisabilities & MUTE)) + message = "" + handled = 1 + if(istype(wear_mask, /obj/item/clothing/mask/horsehead)) + var/obj/item/clothing/mask/horsehead/hoers = wear_mask + if(hoers.voicechange) + if(mind && mind.changeling && department_radio_keys[copytext(message, 1, 3)] != "changeling") + message = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!") + verb = pick("whinnies","neighs", "says") + handled = 1 + + if(dna) + for(var/datum/dna/gene/gene in dna_genes) + if(!gene.block) + continue + if(gene.is_active(src)) + message = gene.OnSay(src,message) + handled = 1 + + if(message != "") + if((HULK in mutations) && health >= 25 && length(message)) + message = "[uppertext(message)]!!!" + verb = pick("yells","roars","hollers") + handled = 1 + if(slurring) + message = slur(message) + verb = "slurs" + handled = 1 + if(stuttering) + message = stutter(message) + verb = "stammers" + handled = 1 + + var/braindam = getBrainLoss() + if(braindam >= 60) + handled = 1 + if(prob(braindam/4)) + message = stutter(message) + verb = "gibbers" + if(prob(braindam)) + message = uppertext(message) + verb = "yells loudly" + + if(COMIC in mutations) + message = "[message]" + returns[1] = message + returns[2] = verb + returns[3] = handled + return returns diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index c920db100a8..d8651518be0 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -236,9 +236,9 @@ proc/get_damage_icon_part(damage_state, body_part) var/hulk_color_mod = rgb(48,224,40) var/necrosis_color_mod = rgb(10,50,0) - var/husk = (M_HUSK in src.mutations) //100% unnecessary -Agouri //nope, do you really want to iterate through src.mutations repeatedly? -Pete - var/fat = (M_FAT in src.mutations) - var/hulk = (M_HULK in src.mutations) + var/husk = (HUSK in src.mutations) //100% unnecessary -Agouri //nope, do you really want to iterate through src.mutations repeatedly? -Pete + var/fat = (FAT in src.mutations) + var/hulk = (HULK in src.mutations) var/g = (gender == FEMALE ? "f" : "m") var/has_head = 0 @@ -290,11 +290,12 @@ proc/get_damage_icon_part(damage_state, body_part) //Robotic limbs are handled in get_icon() so all we worry about are missing or dead limbs. //No icon stored, so we need to start with a basic one. var/datum/organ/external/chest = get_organ("chest") - base_icon = chest.get_icon(g,fat) + if(chest) + base_icon = chest.get_icon(g,fat) - if(chest.status & ORGAN_DEAD) - base_icon.ColorTone(necrosis_color_mod) - base_icon.SetIntensity(0.7) + if(chest.status & ORGAN_DEAD) + base_icon.ColorTone(necrosis_color_mod) + base_icon.SetIntensity(0.7) for(var/datum/organ/external/part in organs) @@ -418,7 +419,7 @@ proc/get_damage_icon_part(damage_state, body_part) if(update_icons) update_icons() return - //masks and helmets can obscure our hair. + //masks and helmets can obscure our hair, unless we're a synthetic if( (head && (head.flags & BLOCKHAIR)) || (wear_mask && (wear_mask.flags & BLOCKHAIR))) if(update_icons) update_icons() return @@ -437,7 +438,7 @@ proc/get_damage_icon_part(damage_state, body_part) else //warning("Invalid f_style for [species.name]: [f_style]") - if(h_style && !(head && (head.flags & BLOCKHEADHAIR))) + if(h_style && !(head && (head.flags & BLOCKHEADHAIR) && !(species.flags & IS_SYNTHETIC))) var/datum/sprite_accessory/hair_style = hair_styles_list[h_style] if(hair_style && hair_style.species_allowed) if(src.species.name in hair_style.species_allowed) @@ -455,7 +456,7 @@ proc/get_damage_icon_part(damage_state, body_part) /mob/living/carbon/human/update_mutations(var/update_icons=1) var/fat - if(M_FAT in mutations) + if(FAT in mutations) fat = "fat" var/image/standing = image("icon" = 'icons/effects/genetics.dmi') @@ -474,26 +475,26 @@ proc/get_damage_icon_part(damage_state, body_part) for(var/mut in mutations) switch(mut) /* - if(M_HULK) + if(HULK) if(fat) standing.underlays += "hulk_[fat]_s" else standing.underlays += "hulk_[g]_s" add_image = 1 - if(M_RESIST_COLD) + if(RESIST_COLD) standing.underlays += "fire[fat]_s" add_image = 1 - if(M_RESIST_HEAT) + if(RESIST_HEAT) standing.underlays += "cold[fat]_s" add_image = 1 if(TK) standing.underlays += "telekinesishead[fat]_s" add_image = 1 */ - if(M_LASER) + if(LASER) standing.overlays += "lasereyes_s" add_image = 1 - if((M_RESIST_COLD in mutations) && (M_RESIST_HEAT in mutations)) + if((RESIST_COLD in mutations) && (RESIST_HEAT in mutations)) standing.underlays -= "cold[fat]_s" standing.underlays -= "fire[fat]_s" standing.underlays += "coldfire[fat]_s" @@ -506,7 +507,7 @@ proc/get_damage_icon_part(damage_state, body_part) /mob/living/carbon/human/proc/update_mutantrace(var/update_icons=1) var/fat - if( M_FAT in mutations ) + if( FAT in mutations ) fat = "fat" // var/g = "m" // if (gender == FEMALE) g = "f" @@ -593,12 +594,12 @@ proc/get_damage_icon_part(damage_state, body_part) if(!t_color) t_color = icon_state var/image/standing = image("icon_state" = "[t_color]_s") - if(M_FAT in mutations) + if(FAT in mutations) if(w_uniform.flags&ONESIZEFITSALL) standing.icon = 'icons/mob/uniform_fat.dmi' else src << "\red You burst out of \the [w_uniform]!" - drop_from_inventory(w_uniform) + unEquip(w_uniform) return else standing.icon = 'icons/mob/uniform.dmi' @@ -614,10 +615,11 @@ proc/get_damage_icon_part(damage_state, body_part) else standing.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "uniformblood") - if(w_uniform:hastie) //WE CHECKED THE TYPE ABOVE. THIS REALLY SHOULD BE FINE. - var/tie_color = w_uniform:hastie._color - if(!tie_color) tie_color = w_uniform:hastie.icon_state - standing.overlays += image("icon" = 'icons/mob/ties.dmi', "icon_state" = "[tie_color]") + if(w_uniform:accessories.len) //WE CHECKED THE TYPE ABOVE. THIS REALLY SHOULD BE FINE. + for(var/obj/item/clothing/accessory/A in w_uniform:accessories) + var/tie_color = A._color + if(!tie_color) tie_color = A.icon_state + standing.overlays += image("icon" = 'icons/mob/ties.dmi', "icon_state" = "[tie_color]") overlays_standing[UNIFORM_LAYER] = standing else @@ -625,7 +627,7 @@ proc/get_damage_icon_part(damage_state, body_part) // Automatically drop anything in store / id / belt if you're not wearing a uniform. //CHECK IF NECESARRY for( var/obj/item/thing in list(r_store, l_store, wear_id, wear_pda, belt) ) // if(thing) // - u_equip(thing) // + unEquip(thing) // if (client) // client.screen -= thing // // @@ -813,19 +815,19 @@ proc/get_damage_icon_part(damage_state, body_part) standing = image("icon" = wear_suit.icon_override, "icon_state" = "[wear_suit.icon_state]") else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[species.name]) standing = image("icon" = wear_suit.sprite_sheets[species.name], "icon_state" = "[wear_suit.icon_state]") - else if(M_FAT in mutations) + else if(FAT in mutations) if(wear_suit.flags&ONESIZEFITSALL) standing = image("icon" = 'icons/mob/suit_fat.dmi', "icon_state" = "[wear_suit.icon_state]") else src << "\red You burst out of \the [wear_suit]!" - drop_from_inventory(wear_suit) + unEquip(wear_suit) return else standing = image("icon" = 'icons/mob/suit.dmi', "icon_state" = "[wear_suit.icon_state]") if( istype(wear_suit, /obj/item/clothing/suit/straight_jacket) ) - drop_from_inventory(handcuffed) + unEquip(handcuffed) drop_l_hand() drop_r_hand() @@ -867,7 +869,7 @@ proc/get_damage_icon_part(damage_state, body_part) if(update_icons) update_icons() /mob/living/carbon/human/update_inv_wear_mask(var/update_icons=1) - if( wear_mask && ( istype(wear_mask, /obj/item/clothing/mask) || istype(wear_mask, /obj/item/clothing/tie) ) ) + if( wear_mask && ( istype(wear_mask, /obj/item/clothing/mask) || istype(wear_mask, /obj/item/clothing/accessory) ) ) wear_mask.screen_loc = ui_mask //TODO var/image/standing @@ -917,7 +919,7 @@ proc/get_damage_icon_part(damage_state, body_part) var/obj/screen/inventory/L = hud_used.adding[8] R.overlays += image("icon"='icons/mob/screen_gen.dmi', "icon_state"="markus") L.overlays += image("icon"='icons/mob/screen_gen.dmi', "icon_state"="gabrielle") - if(istype(handcuffed, /obj/item/weapon/handcuffs/pinkcuffs)) + if(istype(handcuffed, /obj/item/weapon/restraints/handcuffs/pinkcuffs)) overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "pinkcuff1") else overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "handcuff1") @@ -998,6 +1000,30 @@ proc/get_damage_icon_part(damage_state, body_part) update_icons() +/mob/living/carbon/human/proc/start_tail_wagging(var/update_icons=1) + overlays_standing[TAIL_LAYER] = null + + if(species.tail && species.bodyflags & HAS_TAIL) + var/icon/tailw_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]w_s") + tailw_s.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) + + overlays_standing[TAIL_LAYER] = image(tailw_s) + + if(update_icons) + update_icons() + +/mob/living/carbon/human/proc/stop_tail_wagging(var/update_icons=1) + overlays_standing[TAIL_LAYER] = null + + if(species.tail && species.bodyflags & HAS_TAIL) + var/icon/tail_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_s") + tail_s.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) + + overlays_standing[TAIL_LAYER] = image(tail_s) + + if(update_icons) + update_icons() + //Adds a collar overlay above the helmet layer if the suit has one // Suit needs an identically named sprite in icons/mob/collar.dmi /mob/living/carbon/human/proc/update_collar(var/update_icons=1) diff --git a/code/modules/mob/living/carbon/human/whisper.dm b/code/modules/mob/living/carbon/human/whisper.dm index 58bbfc54dec..43e8af94f50 100644 --- a/code/modules/mob/living/carbon/human/whisper.dm +++ b/code/modules/mob/living/carbon/human/whisper.dm @@ -1,11 +1,8 @@ //Lallander was here /mob/living/carbon/human/whisper(message as text) + var/alt_name = "" - message = trim(copytext(strip_html_simple(message), 1, MAX_MESSAGE_LEN)) - - if (!message || silent || miming) - return - + message = trim_strip_html_properly(message) log_whisper("[src.name]/[src.key] : [message]") if (src.client) @@ -16,28 +13,74 @@ if (src.client.handle_spam_prevention(message,MUTE_IC)) return - if (src.stat == 2) return src.say_dead(message) if (src.stat) return - var/alt_name = "" - if (istype(src, /mob/living/carbon/human) && src.name != GetVoice()) - var/mob/living/carbon/human/H = src - alt_name = " (as [H.get_id_name("Unknown")])" - // Mute disability - if (src.sdisabilities & MUTE) - return + if(name != GetVoice()) + alt_name = "(as [get_id_name("Unknown")])" + + //parse the language code and consume it + var/datum/language/speaking = parse_language(message) + if (speaking) + message = copytext(message,2+length(speaking.key)) + + whisper_say(message, speaking, alt_name) + + +//This is used by both the whisper verb and human/say() to handle whispering +/mob/living/carbon/human/proc/whisper_say(var/message, var/datum/language/speaking = null, var/alt_name="", var/verb="whispers") if (istype(src.wear_mask, /obj/item/clothing/mask/muzzle)) + src << "You're muzzled and cannot speak!" return - var/italics = 1 var/message_range = 1 + var/eavesdropping_range = 2 + var/watching_range = 5 + var/italics = 1 - if(istype(src.wear_mask, /obj/item/clothing/mask/gas/voice/space_ninja)&&src.wear_mask:voice=="Unknown") + var/not_heard //the message displayed to people who could not hear the whispering + if (speaking) + if (speaking.whisper_verb) + verb = speaking.whisper_verb + not_heard = "[verb] something" + else + var/adverb = pick("quietly", "softly") + verb = "[speaking.speech_verb] [adverb]" + not_heard = "[speaking.speech_verb] something [adverb]" + else + not_heard = "[verb] something" //TODO get rid of the null language and just prevent speech if language is null + + message = capitalize(trim(message)) + + if(speech_problem_flag) + var/list/handle_r = handle_speech_problems(message) + message = handle_r[1] + verb = handle_r[2] + if(verb == "yells loudly") + verb = "slurs emphatically" + else + var/adverb = pick("quietly", "softly") + verb = "[verb] [adverb]" + + speech_problem_flag = handle_r[3] + + if(!message || message=="") + return + + //looks like this only appears in whisper. Should it be elsewhere as well? Maybe handle_speech_problems? + var/voice_sub + for(var/obj/item/gear in list(wear_mask,wear_suit,head)) + if(!gear) + continue + var/obj/item/voice_changer/changer = locate() in gear + if(changer && changer.active && changer.voice) + voice_sub = changer.voice + + if(voice_sub == "Unknown") if(copytext(message, 1, 2) != "*") var/list/temp_message = text2list(message, " ") var/list/pick_list = list() @@ -49,97 +92,60 @@ temp_message[H] = ninjaspeak(temp_message[H]) pick_list -= H message = list2text(temp_message, " ") - message = replacetext(message, "o", "?") - message = replacetext(message, "p", "?") - message = replacetext(message, "l", "?") - message = replacetext(message, "s", "?") - message = replacetext(message, "u", "?") - message = replacetext(message, "b", "?") - - if (src.stuttering) - message = stutter(message) - - for (var/obj/O in view(message_range, src)) - spawn (0) - if (O) - O.hear_talk(src, message) + message = replacetext(message, "o", "�") + message = replacetext(message, "p", "�") + message = replacetext(message, "l", "�") + message = replacetext(message, "s", "�") + message = replacetext(message, "u", "�") + message = replacetext(message, "b", "�") var/list/listening = hearers(message_range, src) listening |= src + //ghosts + for (var/mob/M in dead_mob_list) //does this include players who joined as observers as well? + if (!(M.client)) + continue + if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTEARS)) + listening |= M + //Pass whispers on to anything inside the immediate listeners. for(var/mob/L in listening) for(var/mob/C in L.contents) if(istype(C,/mob/living)) listening += C - var/list/eavesdropping = hearers(2, src) + //pass on the message to objects that can hear us. + for (var/obj/O in view(message_range, src)) + spawn (0) + if (O) + O.hear_talk(src, message, verb, speaking) + + var/list/eavesdropping = hearers(eavesdropping_range, src) eavesdropping -= src eavesdropping -= listening - var/list/watching = hearers(5, src) + var/list/watching = hearers(watching_range, src) watching -= src watching -= listening watching -= eavesdropping - var/list/heard_a = list() // understood us - var/list/heard_b = list() // didn't understand us + //now mobs + var/speech_bubble_test = say_test(message) + var/image/speech_bubble = image('icons/mob/talk.dmi',src,"h[speech_bubble_test]") + spawn(30) del(speech_bubble) - for (var/mob/M in listening) - if (M.say_understands(src)) - heard_a += M - else - heard_b += M + for(var/mob/M in listening) + M << speech_bubble + M.hear_say(message, verb, speaking, alt_name, italics, src) - var/rendered = null + if (eavesdropping.len) + var/new_message = stars(message) //hopefully passing the message twice through stars() won't hurt... I guess if you already don't understand the language, when they speak it too quietly to hear normally you would be able to catch even less. + for(var/mob/M in eavesdropping) + M << speech_bubble + M.hear_say(new_message, verb, speaking, alt_name, italics, src) - for (var/mob/M in watching) - if (M.say_understands(src)) - rendered = "[src.name] whispers something." - else - rendered = "[src.voice_name] whispers something." - M.show_message(rendered, 2) - - if (length(heard_a)) - var/message_a = message - - if (italics) - message_a = "[message_a]" - //This appears copied from carbon/living say.dm so the istype check for mob is probably not needed. Appending for src is also not needed as the game will check that automatically. - rendered = "[GetVoice()][alt_name] whispers, \"[message_a]\"" - - for (var/mob/M in heard_a) - M.show_message(rendered, 2) - - if (length(heard_b)) - var/message_b - - message_b = stars(message) - - if (italics) - message_b = "[message_b]" - - rendered = "[src.voice_name] whispers, \"[message_b]\"" - - for (var/mob/M in heard_b) - M.show_message(rendered, 2) - - for (var/mob/M in eavesdropping) - if (M.say_understands(src)) - var/message_c - message_c = stars(message) - rendered = "[GetVoice()][alt_name] whispers, \"[message_c]\"" - M.show_message(rendered, 2) - else - rendered = "[src.voice_name] whispers something." - M.show_message(rendered, 2) - - if (italics) - message = "[message]" - rendered = "[GetVoice()][alt_name] whispers, \"[message]\"" - - for (var/mob/M in dead_mob_list) - if (!(M.client)) - continue - if (M.stat > 1 && !(M in heard_a) && (M.client.prefs.toggles & CHAT_GHOSTEARS)) + if (watching.len) + var/rendered = "[src.name] [not_heard]." + for (var/mob/M in watching) M.show_message(rendered, 2) diff --git a/code/modules/mob/living/carbon/metroid/life.dm b/code/modules/mob/living/carbon/metroid/life.dm index f1aa5bea66b..66eba695377 100644 --- a/code/modules/mob/living/carbon/metroid/life.dm +++ b/code/modules/mob/living/carbon/metroid/life.dm @@ -203,7 +203,7 @@ death() return - else if(src.health < config.health_threshold_crit) + else if(src.health <= config.health_threshold_crit) if(!src.reagents.has_reagent("inaprovaline")) src.adjustOxyLoss(10) diff --git a/code/modules/mob/living/carbon/metroid/metroid.dm b/code/modules/mob/living/carbon/metroid/metroid.dm index cb5be464681..598bcacf1d0 100644 --- a/code/modules/mob/living/carbon/metroid/metroid.dm +++ b/code/modules/mob/living/carbon/metroid/metroid.dm @@ -230,7 +230,7 @@ return -/mob/living/carbon/slime/u_equip(obj/item/W as obj) +/mob/living/carbon/slime/unEquip(obj/item/W as obj) return /mob/living/carbon/slime/attack_ui(slot) @@ -255,7 +255,8 @@ if (Victim) return // can't attack while eating! if (health > -100) - + + M.do_attack_animation(src) visible_message(" The [M.name] has glomped [src]!", \ " The [M.name] has glomped [src]!") var/damage = rand(1, 3) @@ -275,6 +276,7 @@ if(M.melee_damage_upper == 0) M.emote("[M.friendly] [src]") else + M.do_attack_animation(src) if(M.attack_sound) playsound(loc, M.attack_sound, 50, 1, 1) visible_message("[M] [M.attacktext] [src]!", \ @@ -308,6 +310,7 @@ if (istype(wear_mask, /obj/item/clothing/mask/muzzle)) return if (health > 0) + M.do_attack_animation(src) attacked += 10 //playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) visible_message("[M.name] has attacked [src]!", \ @@ -316,7 +319,26 @@ updatehealth() return +/mob/living/carbon/slime/attack_larva(mob/living/carbon/alien/larva/L as mob) + switch(L.a_intent) + + if("help") + visible_message("[L] rubs its head against [src].") + + + else + L.do_attack_animation(src) + attacked += 10 + visible_message("[L] bites [src]!", \ + "[L] bites [src]!") + playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) + + if(stat != DEAD) + var/damage = rand(1, 3) + L.amount_grown = min(L.amount_grown + damage, L.max_grown) + adjustBruteLoss(damage) + /mob/living/carbon/slime/attack_hand(mob/living/carbon/human/M as mob) if (!ticker) M << "You cannot attack people before the game has started." @@ -415,12 +437,12 @@ visible_message("[M] has grabbed [src] passively!") else - + M.do_attack_animation(src) var/damage = rand(1, 9) attacked += 10 if (prob(90)) - if (M_HULK in M.mutations) + if (HULK in M.mutations) damage += 5 if(Victim || Target) Victim = null @@ -462,7 +484,7 @@ visible_message("[M] caresses [src] with its scythe like arm.") if ("harm") - + M.do_attack_animation(src) if (prob(95)) attacked += 10 playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1) @@ -496,6 +518,7 @@ visible_message(" [M] has grabbed [name] passively!") if ("disarm") + M.do_attack_animation(src) playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1) var/damage = 5 attacked += 10 @@ -533,7 +556,7 @@ updatehealth() return -/mob/living/carbon/slime/attackby(obj/item/W, mob/user) +/mob/living/carbon/slime/attackby(obj/item/W, mob/user, params) if(istype(W,/obj/item/stack/sheet/mineral/plasma)) //Lets you feed slimes plasma. if (user in Friends) ++Friends[user] @@ -643,7 +666,7 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75 var/Uses = 1 // uses before it goes inert var/enhanced = 0 //has it been enhanced before? - attackby(obj/item/O as obj, mob/user as mob) + attackby(obj/item/O as obj, mob/user as mob, params) if(istype(O, /obj/item/weapon/slimesteroid2)) if(enhanced == 1) user << " This extract has already been enhanced!" @@ -803,7 +826,7 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75 pet.colour = "[M.colour]" user <<"You feed the slime the potion, removing it's powers and calming it." del(M) - var/newname = copytext(sanitize(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text),1,MAX_NAME_LEN) + var/newname = sanitize(copytext(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text,1,MAX_NAME_LEN)) if (!newname) newname = "pet slime" @@ -834,7 +857,7 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75 pet.colour = "[M.colour]" user <<"You feed the slime the potion, removing it's powers and calming it." del(M) - var/newname = copytext(sanitize(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text),1,MAX_NAME_LEN) + var/newname = sanitize(copytext(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text,1,MAX_NAME_LEN)) if (!newname) newname = "pet slime" @@ -897,8 +920,8 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75 item_state = "golem" _color = "golem" has_sensor = 0 + flags = ABSTRACT | NODROP armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) - canremove = 0 /obj/item/clothing/suit/golem name = "adamantine shell" @@ -911,21 +934,19 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75 body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS|HEAD slowdown = 1.0 flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT - flags = FPRINT | TABLEPASS | ONESIZEFITSALL | STOPSPRESSUREDMAGE + flags = ONESIZEFITSALL | STOPSPRESSUREDMAGE | ABSTRACT | NODROP heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS | HEAD max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS | HEAD min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE - canremove = 0 armor = list(melee = 80, bullet = 20, laser = 20, energy = 10, bomb = 0, bio = 0, rad = 0) /obj/item/clothing/shoes/golem name = "golem's feet" desc = "sturdy adamantine feet" icon_state = "golem" - item_state = null - canremove = 0 - flags = NOSLIP + item_state = "golem" + flags = NOSLIP | ABSTRACT | MASKINTERNALS | MASKCOVERSMOUTH | NODROP slowdown = SHOES_SLOWDOWN+1 @@ -934,18 +955,9 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75 desc = "the imposing face of an adamantine golem" icon_state = "golem" item_state = "golem" - canremove = 0 - siemens_coefficient = 0 - unacidable = 1 - -/obj/item/clothing/mask/gas/golem - name = "golem's face" - desc = "the imposing face of an adamantine golem" - icon_state = "golem" - item_state = "golem" - canremove = 0 siemens_coefficient = 0 unacidable = 1 + flags = ABSTRACT | NODROP /obj/item/clothing/gloves/golem @@ -954,7 +966,7 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75 icon_state = "golem" item_state = null siemens_coefficient = 0 - canremove = 0 + flags = ABSTRACT | NODROP /obj/item/clothing/head/space/golem @@ -963,14 +975,13 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75 _color = "dermal" name = "golem's head" desc = "a golem's head" - canremove = 0 unacidable = 1 - flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE + flags = STOPSPRESSUREDMAGE | ABSTRACT | NODROP heat_protection = HEAD max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE armor = list(melee = 80, bullet = 20, laser = 20, energy = 10, bomb = 0, bio = 0, rad = 0) -/obj/effect/golem_rune +/obj/effect/goleRUNe anchored = 1 desc = "a strange rune used to create golems. It glows when spirits are nearby." name = "rune" @@ -1130,7 +1141,7 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75 if (environment.toxins > MOLES_PLASMA_VISIBLE)//plasma exposure causes the egg to hatch src.Hatch() -/obj/item/weapon/reagent_containers/food/snacks/egg/slime/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/reagent_containers/food/snacks/egg/slime/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype( W, /obj/item/toy/crayon )) return else @@ -1142,7 +1153,6 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75 desc = "Allows you to change your slimeperson color, once." icon = 'icons/obj/device.dmi' icon_state = "t-ray0" - flags = TABLEPASS force = 1.0 w_class = 1.0 throwforce = 1.0 diff --git a/code/modules/mob/living/carbon/metroid/say.dm b/code/modules/mob/living/carbon/metroid/say.dm index 89708595da4..f4de10ceb74 100644 --- a/code/modules/mob/living/carbon/metroid/say.dm +++ b/code/modules/mob/living/carbon/metroid/say.dm @@ -21,3 +21,16 @@ return 1 return ..() +/mob/living/carbon/slime/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "", var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol) + if (speaker in Friends) + speech_buffer = list() + speech_buffer.Add(speaker) + speech_buffer.Add(lowertext(html_decode(message))) + ..() + +/mob/living/carbon/slime/hear_radio(var/message, var/verb="says", var/datum/language/language=null, var/part_a, var/part_b, var/mob/speaker = null, var/hard_to_hear = 0, var/vname ="") + if (speaker in Friends) + speech_buffer = list() + speech_buffer.Add(speaker) + speech_buffer.Add(lowertext(html_decode(message))) + ..() diff --git a/code/modules/mob/living/carbon/monkey/diona.dm b/code/modules/mob/living/carbon/monkey/diona.dm index a90868c1c8c..4039156e506 100644 --- a/code/modules/mob/living/carbon/monkey/diona.dm +++ b/code/modules/mob/living/carbon/monkey/diona.dm @@ -193,7 +193,7 @@ adult.rename_self("diona") for (var/obj/item/W in src.contents) - src.drop_from_inventory(W) + src.unEquip(W) del(src) diff --git a/code/modules/mob/living/carbon/monkey/emote.dm b/code/modules/mob/living/carbon/monkey/emote.dm index d5328183f31..c7973bc4eb8 100644 --- a/code/modules/mob/living/carbon/monkey/emote.dm +++ b/code/modules/mob/living/carbon/monkey/emote.dm @@ -9,7 +9,25 @@ if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_' act = copytext(act,1,length(act)) - var/muzzled = istype(src.wear_mask, /obj/item/clothing/mask/muzzle) + var/muzzled = is_muzzled() + + //Emote Cooldown System (it's so simple!) + // proc/handle_emote_CD() located in [code\modules\mob\emote.dm] + var/on_CD = 0 + switch(act) + //Cooldown-inducing emotes + if("chirp") + if(istype(src,/mob/living/carbon/monkey/diona)) //Only Diona Nymphs can chirp + on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm + else //Everyone else fails, skip the emote attempt + return + //Everything else, including typos of the above emotes + else + on_CD = 0 //If it doesn't induce the cooldown, we won't check for the cooldown + + if(on_CD == 1) // Check if we need to suppress the emote attempt. + return // Suppress emote, you're still cooling off. + //--FalseIncarnate switch(act) if ("me") @@ -32,10 +50,9 @@ return custom_emote(m_type, message) if ("chirp") - if(istype(src,/mob/living/carbon/monkey/diona)) - message = "The [src.name] chirps!" - playsound(src.loc, 'sound/misc/nymphchirp.ogg', 50, 0) - m_type = 2 + message = "The [src.name] chirps!" + playsound(src.loc, 'sound/misc/nymphchirp.ogg', 50, 0) + m_type = 2 if("sign") if (!src.restrained()) message = text("The monkey signs[].", (text2num(param) ? text(" the number []", text2num(param)) : null)) diff --git a/code/modules/mob/living/carbon/monkey/inventory.dm b/code/modules/mob/living/carbon/monkey/inventory.dm index cfb4029609f..8ccadd0349c 100644 --- a/code/modules/mob/living/carbon/monkey/inventory.dm +++ b/code/modules/mob/living/carbon/monkey/inventory.dm @@ -41,7 +41,7 @@ var/message = null switch(place) if("mask") - if(istype(target.wear_mask, /obj/item/clothing)&&!target.wear_mask:canremove) + if(istype(target.wear_mask, /obj/item/clothing)&&(target.wear_mask:flags & NODROP)) message = text("\red [] fails to take off \a [] from []'s body!", source, target.wear_mask, target) else message = text("\red [] is trying to take off \a [] from []'s head!", source, target.wear_mask, target) @@ -76,10 +76,10 @@ switch(place) if("mask") if (target.wear_mask) - if(istype(target.wear_mask, /obj/item/clothing)&& !target.wear_mask:canremove) + if(istype(target.wear_mask, /obj/item/clothing)&& (target.wear_mask:flags & NODROP)) return var/obj/item/W = target.wear_mask - target.u_equip(W) + target.unEquip(W) if (target.client) target.client.screen -= W if (W) @@ -97,7 +97,7 @@ if("l_hand") if (target.l_hand) var/obj/item/W = target.l_hand - target.u_equip(W) + target.unEquip(W) if (target.client) target.client.screen -= W if (W) @@ -117,7 +117,7 @@ if("r_hand") if (target.r_hand) var/obj/item/W = target.r_hand - target.u_equip(W) + target.unEquip(W) if (target.client) target.client.screen -= W if (W) @@ -137,7 +137,7 @@ if("back") if (target.back) var/obj/item/W = target.back - target.u_equip(W) + target.unEquip(W) if (target.client) target.client.screen -= W if (W) @@ -155,7 +155,7 @@ if("handcuff") if (target.handcuffed) var/obj/item/W = target.handcuffed - target.u_equip(W) + target.unEquip(W) if (target.client) target.client.screen -= W if (W) @@ -164,7 +164,7 @@ W.layer = initial(W.layer) W.add_fingerprint(source) else - if (istype(item, /obj/item/weapon/handcuffs)) + if (istype(item, /obj/item/weapon/restraints/handcuffs)) source.drop_item() target.handcuffed = item item.loc = target @@ -199,7 +199,7 @@ if(!istype(W)) return if(W == get_active_hand()) - u_equip(W) + unEquip(W) switch(slot) if(slot_back) diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm index 01a5ca76e6d..1cc651fdc32 100644 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ b/code/modules/mob/living/carbon/monkey/life.dm @@ -112,16 +112,19 @@ proc/handle_mutations_and_radiation() if(getFireLoss()) - if((M_RESIST_HEAT in mutations) || prob(50)) + if((RESIST_HEAT in mutations) || prob(50)) switch(getFireLoss()) if(1 to 50) adjustFireLoss(-1) if(51 to 100) adjustFireLoss(-5) - if ((M_HULK in mutations) && health <= 25) - mutations.Remove(M_HULK) - src << "\red You suddenly feel very weak." + if ((HULK in mutations) && health <= 25) + mutations.Remove(HULK) + dna.SetSEState(HULKBLOCK,0) + update_mutations() //update our mutation overlays + status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH //temporary fix until the problem can be solved. + src << "You suddenly feel very weak." Weaken(3) emote("collapse") @@ -421,7 +424,7 @@ if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE) pressure_alert = -1 else - if( !(M_RESIST_COLD in mutations) ) + if( !(RESIST_COLD in mutations) ) adjustBruteLoss( LOW_PRESSURE_DAMAGE ) pressure_alert = -2 else @@ -496,7 +499,7 @@ return 1 //UNCONSCIOUS. NO-ONE IS HOME - if( (getOxyLoss() > 25) || (config.health_threshold_crit > health) ) + if( (getOxyLoss() > 25) || (config.health_threshold_crit >= health) ) if( health <= 20 && prob(1) ) spawn(0) emote("gasp") @@ -561,7 +564,7 @@ proc/handle_regular_hud_updates() - if (stat == 2 || (M_XRAY in mutations)) + if (stat == 2 || (XRAY in mutations)) sight |= SEE_TURFS sight |= SEE_MOBS sight |= SEE_OBJS diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index c3f4c035292..feb0a420f28 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -131,7 +131,7 @@ now_pushing = 1 if(ismob(AM)) var/mob/tmob = AM - if(istype(tmob, /mob/living/carbon/human) && (M_HULK in tmob.mutations)) + if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) if(prob(70)) usr << "\red You fail to push [tmob]'s fat ass out of the way." now_pushing = 0 @@ -190,28 +190,45 @@ health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() return -//mob/living/carbon/monkey/bullet_act(var/obj/item/projectile/Proj)taken care of in living - - -/mob/living/carbon/monkey/attack_paw(mob/M as mob) +/mob/living/carbon/monkey/attack_paw(mob/living/M as mob) ..() if (M.a_intent == "help") help_shake_act(M) else - if ((M.a_intent == "harm" && !( istype(wear_mask, /obj/item/clothing/mask/muzzle) ))) - if ((prob(75) && health > 0)) + if (M.a_intent == "harm" && !(istype(src.wear_mask, /obj/item/clothing/mask/muzzle))) + M.do_attack_animation(src) + if (prob(75)) playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) - for(var/mob/O in viewers(src, null)) - O.show_message("\red [M.name] has bit [name]!", 1) + visible_message("[M.name] bites [name]!", \ + "[M.name] bites [name]!") var/damage = rand(1, 5) - adjustBruteLoss(damage) - health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() + if (health > -100) + adjustBruteLoss(damage) + health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() else - for(var/mob/O in viewers(src, null)) - O.show_message("\red [M.name] has attempted to bite [name]!", 1) + visible_message("[M.name] has attempted to bite [name]!", \ + "[M.name] has attempted to bite [name]!") return +/mob/living/carbon/monkey/attack_larva(mob/living/carbon/alien/larva/L as mob) + + switch(L.a_intent) + if("help") + visible_message("[L] rubs its head against [src].") + + + else + L.do_attack_animation(src) + var/damage = rand(1, 3) + visible_message("[L] bites [src]!", \ + "[L] bites [src]!") + playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) + + if(stat != DEAD) + L.amount_grown = min(L.amount_grown + damage, L.max_grown) + adjustBruteLoss(damage) + /mob/living/carbon/monkey/attack_hand(mob/living/carbon/human/M as mob) if (!ticker) M << "You cannot attack people before the game has started." @@ -221,33 +238,35 @@ M << "No attacking people at spawn, you jackass." return + if(..()) //To allow surgery to return properly. + return + if (M.a_intent == "help") help_shake_act(M) + else if (M.a_intent == "harm") - if ((prob(75) && health > 0)) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has punched [name]!", M), 1) + M.do_attack_animation(src) + if (prob(75)) + visible_message("[M] has punched [name]!", \ + "[M] has punched [name]!") playsound(loc, "punch", 25, 1, -1) var/damage = rand(5, 10) if (prob(40)) damage = rand(10, 15) - if (paralysis < 5) + if ( (paralysis < 5) && (health > 0) ) Paralyse(rand(10, 15)) spawn( 0 ) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has knocked out [name]!", M), 1) + visible_message("[M] has knocked out [name]!", \ + "[M] has knocked out [name]!") return adjustBruteLoss(damage) updatehealth() else playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has attempted to punch [name]!", M), 1) + visible_message("[M] has attempted to punch [name]!", \ + "[M] has attempted to punch [name]!") else if (M.a_intent == "grab") if (M == src || anchored) @@ -257,28 +276,24 @@ M.put_in_active_hand(G) - grabbed_by += G G.synch() LAssailant = M playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - for(var/mob/O in viewers(src, null)) - O.show_message(text("\red [] has grabbed [name] passively!", M), 1) + visible_message("[M] has grabbed [name] passively!") else if (!( paralysis )) if (prob(25)) Paralyse(2) playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has pushed down [name]!", M), 1) + visible_message("[M] has pushed down [src]!", \ + "[M] has pushed down [src]!") else - drop_item() - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has disarmed [name]!", M), 1) + if(drop_item()) + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + visible_message("[M] has disarmed [src]!", \ + "[M] has disarmed [src]!") return /mob/living/carbon/monkey/attack_alien(mob/living/carbon/alien/humanoid/M as mob) @@ -292,11 +307,10 @@ switch(M.a_intent) if ("help") - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\blue [M] caresses [src] with its scythe like arm."), 1) + visible_message(" [M] caresses [src] with its scythe like arm.") if ("harm") + M.do_attack_animation(src) if ((prob(95) && health > 0)) playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1) var/damage = rand(15, 30) @@ -304,50 +318,45 @@ damage = rand(20, 40) if (paralysis < 15) Paralyse(rand(10, 15)) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has wounded [name]!", M), 1) + visible_message("[M] has wounded [name]!", \ + "[M] has wounded [name]!") else - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has slashed [name]!", M), 1) - adjustBruteLoss(damage) - updatehealth() + visible_message("[M] has slashed [name]!", \ + "[M] has slashed [name]!") + if (stat != DEAD) + adjustBruteLoss(damage) + updatehealth() else playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has attempted to lunge at [name]!", M), 1) + visible_message("[M] has attempted to lunge at [name]!", \ + "[M] has attempted to lunge at [name]!") if ("grab") - if (M == src) + if (M == src || anchored) return - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src ) + var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src ) M.put_in_active_hand(G) - grabbed_by += G G.synch() LAssailant = M playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - for(var/mob/O in viewers(src, null)) - O.show_message(text("\red [] has grabbed [name] passively!", M), 1) + visible_message("[M] has grabbed [name] passively!") if ("disarm") + M.do_attack_animation(src) playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1) var/damage = 5 if(prob(95)) - Weaken(15) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has tackled down [name]!", M), 1) + Weaken(10) + visible_message("[M] has tackled down [name]!", \ + "[M] has tackled down [name]!") else - drop_item() - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has disarmed [name]!", M), 1) + if(drop_item()) + visible_message("[M] has disarmed [name]!", \ + "[M] has disarmed [name]!") adjustBruteLoss(damage) updatehealth() return @@ -356,12 +365,12 @@ if(M.melee_damage_upper == 0) M.emote("[M.friendly] [src]") else + M.do_attack_animation(src) if(M.attack_sound) playsound(loc, M.attack_sound, 50, 1, 1) - for(var/mob/O in viewers(src, null)) - O.show_message("\red [M] [M.attacktext] [src]!", 1) - M.attack_log += text("\[[time_stamp()]\] attacked [src.name] ([src.ckey])") - src.attack_log += text("\[[time_stamp()]\] was attacked by [M.name] ([M.ckey])") + visible_message("[M] [M.attacktext] [src]!", \ + "[M] [M.attacktext] [src]!") + add_logs(M, src, "attacked", admin=0) var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) adjustBruteLoss(damage) updatehealth() @@ -376,9 +385,9 @@ if (health > -100) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red The [M.name] glomps []!", src), 1) + M.do_attack_animation(src) + visible_message("The [M.name] glomps [src]!", \ + "The [M.name] glomps [src]!") var/damage = rand(1, 3) @@ -406,9 +415,8 @@ if(M.powerlevel < 0) M.powerlevel = 0 - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red The [M.name] has shocked []!", src), 1) + visible_message("[M] shocked [src]!", \ + "[M] shocked [src]!") Weaken(power) if (stuttering < power) diff --git a/code/modules/mob/living/carbon/monkey/say.dm b/code/modules/mob/living/carbon/monkey/say.dm new file mode 100644 index 00000000000..9a629c358fc --- /dev/null +++ b/code/modules/mob/living/carbon/monkey/say.dm @@ -0,0 +1,28 @@ +/mob/living/carbon/monkey/say(var/message) + var/verb = "says" + var/message_range = world.view + + if(client) + if(client.prefs.muted & MUTE_IC) + src << "\red You cannot speak in IC (Muted)." + return + + message = trim_strip_html_properly(message) + + if(stat == 2) + return say_dead(message) + + if(copytext(message,1,2) == "*") + return emote(copytext(message,2)) + + var/datum/language/speaking = parse_language(message) + + if(speaking) + message = copytext(message, 2+length(speaking.key)) + + message = trim(message) + + if(!message || stat) + return + + ..(message, speaking, verb, null, null, message_range, null) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/species.dm b/code/modules/mob/living/carbon/species.dm index 6512ee05247..7693a1d1eb9 100644 --- a/code/modules/mob/living/carbon/species.dm +++ b/code/modules/mob/living/carbon/species.dm @@ -8,10 +8,10 @@ var/icobase = 'icons/mob/human_races/r_human.dmi' // Normal icon set. var/deform = 'icons/mob/human_races/r_def_human.dmi' // Mutated icon set. var/eyes = "eyes_s" // Icon for eyes. + var/blurb = "A completely nondescript species." // A brief lore summary for use in the chargen screen. var/primitive // Lesser form, if any (ie. monkey for humans) var/tail // Name of tail image in species effects icon file. - var/language // Default racial language, if any. var/unarmed //For empty hand harm-intent attack var/unarmed_type = /datum/unarmed_attack var/mutantrace // Safeguard due to old code. @@ -41,11 +41,8 @@ var/brute_mod = null // Physical damage reduction/malus. var/burn_mod = null // Burn damage reduction/malus. - // For grays var/max_hurt_damage = 9 // Max melee damage dealt + 5 if hulk - var/list/default_mutations = list() - var/list/default_blocks = list() // Don't touch. - var/list/default_block_names = list() // Use this instead, using the names from setupgame.dm + var/list/default_genes = list() var/flags = 0 // Various specific features. var/bloodflags=0 @@ -60,12 +57,21 @@ //Used in icon caching. var/race_key = 0 var/icon/icon_template - + + // Language/culture vars. + var/default_language = "Galactic Common" // Default language is used when 'say' is used without modifiers. + var/language = "Galactic Common" // Default racial language, if any. + var/secondary_langs = list() // The names of secondary languages that are available to this species. + var/list/speech_sounds // A list of sounds to potentially play when speaking. + var/list/speech_chance // The likelihood of a speech sound playing. /datum/species/New() unarmed = new unarmed_type() - +/datum/species/proc/get_random_name(var/gender) + var/datum/language/species_language = all_languages[language] + return species_language.get_random_name(gender) + /datum/species/proc/create_organs(var/mob/living/carbon/human/H) //Handles creation of mob organs. //This is a basic humanoid limb setup. H.organs = list() @@ -81,7 +87,7 @@ H.organs_by_name["l_foot"] = new/datum/organ/external/l_foot(H.organs_by_name["l_leg"]) H.organs_by_name["r_foot"] = new/datum/organ/external/r_foot(H.organs_by_name["r_leg"]) - if (name!="Slime People") + if (name != "Slime People") new/datum/organ/internal/heart(H) new/datum/organ/internal/lungs(H) new/datum/organ/internal/liver(H) @@ -202,7 +208,7 @@ spawn(0) H.emote(pick("giggle", "laugh")) SA.moles = 0 - if( (abs(310.15 - breath.temperature) > 50) && !(M_RESIST_HEAT in H.mutations)) // Hot air hurts :( + if( (abs(310.15 - breath.temperature) > 50) && !(RESIST_HEAT in H.mutations)) // Hot air hurts :( if(H.status_flags & GODMODE) return 1 //godmode if(breath.temperature < cold_level_1) if(prob(20)) @@ -247,6 +253,10 @@ return 1 /datum/species/proc/handle_post_spawn(var/mob/living/carbon/C) //Handles anything not already covered by basic species assignment. + handle_dna(C) + return + +/datum/species/proc/handle_dna(var/mob/living/carbon/C, var/remove) //Handles DNA mutations, as that doesn't work at init. return // Used for species-specific names (Vox, etc) @@ -262,6 +272,10 @@ return message /datum/species/proc/equip(var/mob/living/carbon/human/H) + return + +/datum/species/proc/can_understand(var/mob/other) + return /datum/species/human name = "Human" @@ -272,17 +286,29 @@ flags = HAS_LIPS | HAS_UNDERWEAR | CAN_BE_FAT bodyflags = HAS_SKIN_TONE unarmed_type = /datum/unarmed_attack/punch + blurb = "Humanity originated in the Sol system, and over the last five centuries has spread \ + colonies across a wide swathe of space. They hold a wide range of forms and creeds.

\ + While the central Sol government maintains control of its far-flung people, powerful corporate \ + interests, rampant cyber and bio-augmentation and secretive factions make life on most human \ + worlds tumultous at best." /datum/species/unathi name = "Unathi" icobase = 'icons/mob/human_races/r_lizard.dmi' deform = 'icons/mob/human_races/r_def_lizard.dmi' path = /mob/living/carbon/human/unathi + default_language = "Galactic Common" language = "Sinta'unathi" tail = "sogtail" unarmed_type = /datum/unarmed_attack/claws primitive = /mob/living/carbon/monkey/unathi darksight = 3 + + blurb = "A heavily reptillian species, Unathi (or 'Sinta as they call themselves) hail from the \ + Uuosa-Eso system, which roughly translates to 'burning mother'.

Coming from a harsh, radioactive \ + desert planet, they mostly hold ideals of honesty, virtue, martial combat and bravery above all \ + else, frequently even their own lives. They prefer warmer temperatures than most species and \ + their native tongue is a heavy hissing laungage called Sinta'Unathi." flags = HAS_LIPS | HAS_UNDERWEAR bodyflags = FEET_CLAWS | HAS_TAIL | HAS_SKIN_COLOR @@ -305,10 +331,17 @@ icobase = 'icons/mob/human_races/r_tajaran.dmi' deform = 'icons/mob/human_races/r_def_tajaran.dmi' path = /mob/living/carbon/human/tajaran + default_language = "Galactic Common" language = "Siik'tajr" tail = "tajtail" unarmed_type = /datum/unarmed_attack/claws darksight = 8 + + blurb = "The Tajaran race is a species of feline-like bipeds hailing from the planet of Ahdomai in the \ + S'randarr system. They have been brought up into the space age by the Humans and Skrell, and have been \ + influenced heavily by their long history of Slavemaster rule. They have a structured, clan-influenced way \ + of family and politics. They prefer colder environments, and speak a variety of languages, mostly Siik'Maas, \ + using unique inflections their mouths form." cold_level_1 = 200 cold_level_2 = 140 @@ -321,19 +354,30 @@ primitive = /mob/living/carbon/monkey/tajara flags = HAS_LIPS | HAS_UNDERWEAR | CAN_BE_FAT - bodyflags = FEET_PADDED | HAS_TAIL | HAS_SKIN_COLOR + bodyflags = FEET_PADDED | HAS_TAIL | HAS_SKIN_COLOR | TAIL_WAGGING flesh_color = "#AFA59E" base_color = "#333333" +/datum/species/tajaran/handle_death(var/mob/living/carbon/human/H) + + H.stop_tail_wagging(1) + /datum/species/skrell name = "Skrell" icobase = 'icons/mob/human_races/r_skrell.dmi' deform = 'icons/mob/human_races/r_def_skrell.dmi' path = /mob/living/carbon/human/skrell + default_language = "Galactic Common" language = "Skrellian" primitive = /mob/living/carbon/monkey/skrell unarmed_type = /datum/unarmed_attack/punch + + blurb = "An amphibious species, Skrell come from the star system known as Qerr'Vallis, which translates to 'Star of \ + the royals' or 'Light of the Crown'.

Skrell are a highly advanced and logical race who live under the rule \ + of the Qerr'Katish, a caste within their society which keeps the empire of the Skrell running smoothly. Skrell are \ + herbivores on the whole and tend to be co-operative with the other species of the galaxy, although they rarely reveal \ + the secrets of their empire to their allies." flags = HAS_LIPS | HAS_UNDERWEAR bloodflags = BLOOD_GREEN @@ -348,8 +392,20 @@ icobase = 'icons/mob/human_races/r_vox.dmi' deform = 'icons/mob/human_races/r_def_vox.dmi' path = /mob/living/carbon/human/vox - language = "Vox-pidgin" + + default_language = "Galactic Common" + language = "Vox-pidgin" + speech_sounds = list('sound/voice/shriek1.ogg') + speech_chance = 20 + unarmed_type = /datum/unarmed_attack/claws //I dont think it will hurt to give vox claws too. + + blurb = "The Vox are the broken remnants of a once-proud race, now reduced to little more than \ + scavenging vermin who prey on isolated stations, ships or planets to keep their own ancient arkships \ + alive. They are four to five feet tall, reptillian, beaked, tailed and quilled; human crews often \ + refer to them as 'shitbirds' for their violent and offensive nature, as well as their horrible \ + smell.

Most humans will never meet a Vox raider, instead learning of this insular species through \ + dealing with their traders and merchants; those that do rarely enjoy the experience." warning_low_pressure = 50 hazard_low_pressure = 0 @@ -393,7 +449,6 @@ name = "Vox Armalis" icobase = 'icons/mob/human_races/r_armalis.dmi' deform = 'icons/mob/human_races/r_armalis.dmi' - language = "Vox-pidgin" path = /mob/living/carbon/human/voxarmalis unarmed_type = /datum/unarmed_attack/claws/armalis @@ -454,20 +509,19 @@ icobase = 'icons/mob/human_races/r_kidan.dmi' deform = 'icons/mob/human_races/r_def_kidan.dmi' path = /mob/living/carbon/human/kidan + default_language = "Galactic Common" language = "Chittin" unarmed_type = /datum/unarmed_attack/claws - brute_mod = 0.8 flags = IS_WHITELISTED bloodflags = BLOOD_GREEN bodyflags = FEET_CLAWS - - /datum/species/slime name = "Slime People" + default_language = "Galactic Common" language = "Bubblish" path = /mob/living/carbon/human/slime primitive = /mob/living/carbon/slime @@ -478,37 +532,48 @@ /datum/species/slime/handle_post_spawn(var/mob/living/carbon/human/H) H.dna = new /datum/dna(null) - H.dna.species=H.species.name + H.dna.real_name = H.real_name + H.dna.species = H.species.name H.dna.mutantrace = "slime" - H.update_mutantrace() - return ..() + ..() -/datum/species/grey // /vg/ +/datum/species/grey name = "Grey" icobase = 'icons/mob/human_races/r_grey.dmi' deform = 'icons/mob/human_races/r_def_grey.dmi' - language = "Grey" + default_language = "Galactic Common" + //language = "Grey" // Perhaps if they ever get a hivemind unarmed_type = /datum/unarmed_attack/punch darksight = 5 // BOOSTED from 2 eyes = "grey_eyes_s" brute_mod = 1.25 //greys are fragile + + default_genes = list(REMOTE_TALK) primitive = /mob/living/carbon/monkey // TODO flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | CAN_BE_FAT - - // Both must be set or it's only a 45% chance of manifesting. - default_mutations=list(M_REMOTE_TALK) - default_block_names=list("REMOTETALK") - + +/datum/species/grey/handle_dna(var/mob/living/carbon/C, var/remove) + if(!remove) + C.dna.SetSEState(REMOTETALKBLOCK,1,1) + C.mutations |= REMOTE_TALK + genemutcheck(C,REMOTETALKBLOCK,null,MUTCHK_FORCED) + else + C.dna.SetSEState(REMOTETALKBLOCK,0,1) + C.mutations -= REMOTE_TALK + genemutcheck(C,REMOTETALKBLOCK,null,MUTCHK_FORCED) + C.update_mutations() + ..() /datum/species/diona name = "Diona" icobase = 'icons/mob/human_races/r_diona.dmi' deform = 'icons/mob/human_races/r_def_plant.dmi' path = /mob/living/carbon/human/diona + default_language = "Galactic Common" language = "Rootspeak" unarmed_type = /datum/unarmed_attack/diona primitive = /mob/living/carbon/monkey/diona @@ -523,6 +588,14 @@ heat_level_1 = 300 heat_level_2 = 350 heat_level_3 = 700 + + blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \ + species hailing from Epsilon Ursae Minoris. Each 'diona' is a cluster of numerous cat-sized organisms called nymphs; \ + there is no effective upper limit to the number that can fuse in gestalt, and reports exist of the Epsilon Ursae \ + Minoris primary being ringed with a cloud of singing space-station-sized entities.

The Dionaea coexist peacefully with \ + all known species, especially the Skrell. Their communal mind makes them slow to react, and they have difficulty understanding \ + even the simplest concepts of other minds. Their alien physiology allows them survive happily off a diet of nothing but light, \ + water and other radiation." flags = NO_BREATHE | REQUIRE_LIGHT | IS_PLANT | RAD_ABSORB | NO_BLOOD | IS_SLOW | NO_PAIN @@ -532,6 +605,12 @@ flesh_color = "#907E4A" reagent_tag = IS_DIONA + +/datum/species/diona/can_understand(var/mob/other) + var/mob/living/carbon/monkey/diona/D = other + if(istype(D)) + return 1 + return 0 /datum/species/diona/handle_post_spawn(var/mob/living/carbon/human/H) H.gender = NEUTER @@ -561,6 +640,7 @@ icobase = 'icons/mob/human_races/r_machine.dmi' deform = 'icons/mob/human_races/r_machine.dmi' path = /mob/living/carbon/human/machine + default_language = "Galactic Common" language = "Trinary" unarmed_type = /datum/unarmed_attack/punch diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index 9126dc6bd95..13676d438a9 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -15,7 +15,7 @@ if(BRUTE) adjustBruteLoss(damage * blocked) if(BURN) - if(M_RESIST_HEAT in mutations) damage = 0 + if(RESIST_HEAT in mutations) damage = 0 adjustFireLoss(damage * blocked) if(TOX) adjustToxLoss(damage * blocked) @@ -58,6 +58,8 @@ halloss += effect // Useful for objects that cause "subdual" damage. PAIN! if(IRRADIATE) radiation += max(effect * ((100-run_armor_check(null, "rad", "Your clothes feel warm.", "Your clothes feel warm."))/100),0)//Rads auto check armor + if(SLUR) + slurring = max(slurring,(effect * blocked)) if(STUTTER) if(status_flags & CANSTUN) // stun is usually associated with stutter stuttering = max(stuttering,(effect * blocked)) @@ -66,7 +68,8 @@ if(DROWSY) drowsyness = max(drowsyness,(effect * blocked)) if(JITTER) - jitteriness = max(jitteriness,(effect * blocked)) + if(status_flags & CANSTUN) + jitteriness = max(jitteriness,(effect * blocked)) updatehealth() return 1 @@ -80,12 +83,13 @@ /mob/living/carbon/apply_effect(var/effect = 0,var/effecttype = STUN, var/blocked = 0) return ..() -/mob/living/proc/apply_effects(var/stun = 0, var/weaken = 0, var/paralyze = 0, var/irradiate = 0, var/stutter = 0, var/eyeblur = 0, var/drowsy = 0, var/agony = 0, var/blocked = 0, var/stamina = 0, var/jitter = 0) +/mob/living/proc/apply_effects(var/stun = 0, var/weaken = 0, var/paralyze = 0, var/irradiate = 0, var/slur = 0, var/stutter = 0, var/eyeblur = 0, var/drowsy = 0, var/agony = 0, var/blocked = 0, var/stamina = 0, var/jitter = 0) if(blocked >= 100) return 0 if(stun) apply_effect(stun, STUN, blocked) if(weaken) apply_effect(weaken, WEAKEN, blocked) if(paralyze) apply_effect(paralyze, PARALYZE, blocked) if(irradiate) apply_effect(irradiate, IRRADIATE, blocked) + if(slur) apply_effect(slur, SLUR, blocked) if(stutter) apply_effect(stutter, STUTTER, blocked) if(eyeblur) apply_effect(eyeblur, EYE_BLUR, blocked) if(drowsy) apply_effect(drowsy, DROWSY, blocked) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 791c1b64d88..15991b13201 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -23,11 +23,15 @@ */ /mob/living/verb/succumb() set hidden = 1 - if ((src.health < 0 && src.health > -95.0)) - src.adjustOxyLoss(src.health + 200) - src.health = 100 - src.getOxyLoss() - src.getToxLoss() - src.getFireLoss() - src.getBruteLoss() - src << "\blue You have given up life and succumbed to death." + if (InCritical()) + src.attack_log += "[src] has ["succumbed to death"] with [round(health, 0.1)] points of health!" + src.adjustOxyLoss(src.health - config.health_threshold_dead) + updatehealth() + src << "You have given up life and succumbed to death." + death() +/mob/living/proc/InCritical() + return (src.health < 0 && src.health > -95.0 && stat == UNCONSCIOUS) /mob/living/proc/updatehealth() if(status_flags & GODMODE) @@ -47,9 +51,7 @@ /mob/living/proc/burn_skin(burn_amount) if(istype(src, /mob/living/carbon/human)) //world << "DEBUG: burn_skin(), mutations=[mutations]" - if(M_NO_SHOCK in src.mutations) //shockproof - return 0 - if (M_RESIST_HEAT in src.mutations) //fireproof + if (RESIST_HEAT in src.mutations) //fireproof return 0 var/mob/living/carbon/human/H = src //make this damage method divide the damage to be done among all the body parts, then burn each body part for that much damage. will have better effect then just randomly picking a body part var/divided_damage = (burn_amount)/(H.organs.len) @@ -61,7 +63,7 @@ H.updatehealth() return 1 else if(istype(src, /mob/living/carbon/monkey)) - if (M_RESIST_HEAT in src.mutations) //fireproof + if (RESIST_HEAT in src.mutations) //fireproof return 0 var/mob/living/carbon/monkey/M = src M.adjustFireLoss(burn_amount) @@ -216,7 +218,7 @@ L += get_contents(S) for(var/obj/item/clothing/suit/storage/S in src.contents)//Check for labcoats and jackets L += get_contents(S) - for(var/obj/item/clothing/tie/storage/S in src.contents)//Check for holsters + for(var/obj/item/clothing/accessory/storage/S in src.contents)//Check for holsters L += get_contents(S) for(var/obj/item/weapon/gift/G in src.contents) //Check for gift-wrapped items L += G.gift @@ -227,6 +229,9 @@ L += D.wrapped if(istype(D.wrapped, /obj/item/weapon/storage)) //this should never happen L += get_contents(D.wrapped) + for(var/obj/item/weapon/folder/F in src.contents) + L += F.contents //Folders can't store any storage items. + return L /mob/living/proc/check_contents_for(A) @@ -286,11 +291,11 @@ var/mob/living/carbon/C = src if (C.handcuffed && !initial(C.handcuffed)) - C.drop_from_inventory(C.handcuffed) + C.unEquip(C.handcuffed) C.handcuffed = initial(C.handcuffed) if (C.legcuffed && !initial(C.legcuffed)) - C.drop_from_inventory(C.legcuffed) + C.unEquip(C.legcuffed) C.legcuffed = initial(C.legcuffed) hud_updateflag |= 1 << HEALTH_HUD hud_updateflag |= 1 << STATUS_HUD @@ -456,7 +461,7 @@ if(!isliving(usr) || usr.next_move > world.time) return - usr.next_move = world.time + 20 + usr.changeNext_move(CLICK_CD_RESIST) var/mob/living/L = usr @@ -466,7 +471,7 @@ var/mob/M = H.loc //Get our mob holder (if any). if(istype(M)) - M.drop_from_inventory(H) + M.unEquip(H) M << "[H] wriggles out of your grip!" src << "You wriggle out of [M]'s grip!" else if(istype(H.loc,/obj/item)) @@ -539,8 +544,8 @@ if(iscarbon(L)) var/mob/living/carbon/C = L if( C.handcuffed ) - C.next_move = world.time + 100 - C.last_special = world.time + 100 + C.changeNext_move(CLICK_CD_BREAKOUT) + C.last_special = world.time + CLICK_CD_BREAKOUT C << "\red You attempt to unbuckle yourself. (This will take around 2 minutes and you need to stand still)" for(var/mob/O in viewers(L)) O.show_message("\red [usr] attempts to unbuckle themself!", 1) @@ -573,8 +578,8 @@ // breakout_time++ //Harder to get out of welded lockers than locked lockers //okay, so the closet is either welded or locked... resist!!! - usr.next_move = world.time + 100 - L.last_special = world.time + 100 + L.changeNext_move(CLICK_CD_BREAKOUT) + L.last_special = world.time + CLICK_CD_BREAKOUT L << "\red You lean on the back of \the [C] and start pushing the door open. (this will take about [breakout_time] minutes)" for(var/mob/O in viewers(usr.loc)) O.show_message("\red The [L.loc] begins to shake violently!", 1) @@ -629,7 +634,8 @@ var/mob/living/carbon/CM = L if(CM.on_fire && CM.canmove) CM.fire_stacks -= 5 - CM.Weaken(3) + CM.weakened = max(CM.weakened, 3)//We dont check for CANWEAKEN, I don't care how immune to weakening you are, if you're rolling on the ground, you're busy. + CM.update_canmove() CM.spin(32,2) CM.visible_message("[CM] rolls on the floor, trying to put themselves out!", \ "You stop, drop, and roll!") @@ -640,9 +646,9 @@ ExtinguishMob() return if(CM.handcuffed && CM.canmove && (CM.last_special <= world.time)) - CM.next_move = world.time + 100 - CM.last_special = world.time + 100 - if(isalienadult(CM) || (M_HULK in usr.mutations))//Don't want to do a lot of logic gating here. + CM.changeNext_move(CLICK_CD_BREAKOUT) + CM.last_special = world.time + CLICK_CD_BREAKOUT + if(isalienadult(CM) || (HULK in usr.mutations))//Don't want to do a lot of logic gating here. usr << "\red You attempt to break your handcuffs. (This will take around 5 seconds and you need to stand still)" for(var/mob/O in viewers(CM)) O.show_message(text("\red [] is trying to break the handcuffs!", CM), 1) @@ -658,8 +664,8 @@ CM.handcuffed = null CM.update_inv_handcuffed() else - var/obj/item/weapon/handcuffs/HC = CM.handcuffed - var/breakouttime = 1200 //A default in case you are somehow handcuffed with something that isn't an obj/item/weapon/handcuffs type + var/obj/item/weapon/restraints/handcuffs/HC = CM.handcuffed + var/breakouttime = 1200 //A default in case you are somehow handcuffed with something that isn't an obj/item/weapon/restraints/handcuffs type var/displaytime = 2 //Minutes to display in the "this will take X minutes." if(istype(HC)) //If you are handcuffed with actual handcuffs... Well what do I know, maybe someone will want to handcuff you with toilet paper in the future... breakouttime = HC.breakouttime @@ -674,12 +680,12 @@ for(var/mob/O in viewers(CM))// lags so hard that 40s isn't lenient enough - Quarxink O.show_message("\red [CM] manages to remove the handcuffs!", 1) CM << "\blue You successfully remove \the [CM.handcuffed]." - CM.drop_from_inventory(CM.handcuffed) + CM.unEquip(CM.handcuffed) else if(CM.legcuffed && CM.canmove && (CM.last_special <= world.time)) - CM.next_move = world.time + 100 - CM.last_special = world.time + 100 - if(isalienadult(CM) || (M_HULK in usr.mutations))//Don't want to do a lot of logic gating here. + CM.changeNext_move(CLICK_CD_BREAKOUT) + CM.last_special = world.time + CLICK_CD_BREAKOUT + if(isalienadult(CM) || (HULK in usr.mutations))//Don't want to do a lot of logic gating here. usr << "\red You attempt to break your legcuffs. (This will take around 5 seconds and you need to stand still)" for(var/mob/O in viewers(CM)) O.show_message(text("\red [] is trying to break the legcuffs!", CM), 1) @@ -695,7 +701,7 @@ CM.legcuffed = null CM.update_inv_legcuffed() else - var/obj/item/weapon/legcuffs/HC = CM.legcuffed + var/obj/item/weapon/restraints/legcuffs/HC = CM.legcuffed var/breakouttime = 1200 //A default in case you are somehow legcuffed with something that isn't an obj/item/weapon/legcuffs type var/displaytime = 2 //Minutes to display in the "this will take X minutes." if(istype(HC)) //If you are legcuffed with actual legcuffs... Well what do I know, maybe someone will want to legcuff you with toilet paper in the future... @@ -711,7 +717,7 @@ for(var/mob/O in viewers(CM))// lags so hard that 40s isn't lenient enough - Quarxink O.show_message("\red [CM] manages to remove the legcuffs!", 1) CM << "\blue You successfully remove \the [CM.legcuffed]." - CM.drop_from_inventory(CM.legcuffed) + CM.unEquip(CM.legcuffed) CM.legcuffed = null CM.update_inv_legcuffed() @@ -761,3 +767,45 @@ /mob/living/proc/can_use_vents() return "You can't fit into that vent." + + + +/atom/movable/proc/do_attack_animation(atom/A) + var/pixel_x_diff = 0 + var/pixel_y_diff = 0 + var/direction = get_dir(src, A) + switch(direction) + if(NORTH) + pixel_y_diff = 8 + if(SOUTH) + pixel_y_diff = -8 + if(EAST) + pixel_x_diff = 8 + if(WEST) + pixel_x_diff = -8 + if(NORTHEAST) + pixel_x_diff = 8 + pixel_y_diff = 8 + if(NORTHWEST) + pixel_x_diff = -8 + pixel_y_diff = 8 + if(SOUTHEAST) + pixel_x_diff = 8 + pixel_y_diff = -8 + if(SOUTHWEST) + pixel_x_diff = -8 + pixel_y_diff = -8 + animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, time = 2) + animate(pixel_x = initial(pixel_x), pixel_y = initial(pixel_y), time = 2) + +/mob/living/do_attack_animation(atom/A) + ..() + floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement. + +/mob/living/proc/do_jitter_animation(jitteriness) + var/amplitude = min(4, (jitteriness/100) + 1) + var/pixel_x_diff = rand(-amplitude, amplitude) + var/pixel_y_diff = rand(-amplitude/3, amplitude/3) + animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff , time = 2, loop = 6) + animate(pixel_x = initial(pixel_x) , pixel_y = initial(pixel_y) , time = 2) + floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement. diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 52019fc923e..cad2c176aa6 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -223,19 +223,21 @@ /mob/living/proc/IgniteMob() if(fire_stacks > 0) on_fire = 1 + src.AddLuminosity(3) update_fire() /mob/living/proc/ExtinguishMob() if(on_fire) on_fire = 0 fire_stacks = 0 + src.AddLuminosity(-3) update_fire() /mob/living/proc/update_fire() return /mob/living/proc/adjust_fire_stacks(add_fire_stacks) //Adjusting the amount of fire_stacks we have on person - fire_stacks = Clamp(fire_stacks + add_fire_stacks, min = -20, max = 20) + fire_stacks = Clamp(fire_stacks + add_fire_stacks, min = -20, max = 20) /mob/living/proc/handle_fire() if(fire_stacks < 0) @@ -243,25 +245,15 @@ fire_stacks = min(0, fire_stacks)//So we dry ourselves back to default, nonflammable. if(!on_fire) return 1 - - var/oxy=0 - var/turf/T=loc - if(istype(T)) - if(istype(T,/turf/space)) - ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire - return 1 - var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment - if(G) - oxy=G.oxygen - if(oxy < 10 || fire_stacks <= 0) + var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment + if(G.oxygen < 1) ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire - return 1 + return var/turf/location = get_turf(src) location.hotspot_expose(700, 50, 1) /mob/living/fire_act() - adjust_fire_stacks(5) - if(fire_stacks > 9 && !on_fire) - IgniteMob() + adjust_fire_stacks(0.5) + IgniteMob() //Mobs on Fire end diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index bad5c10d9e0..b5ec333f1fa 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -1,25 +1,22 @@ var/list/department_radio_keys = list( - ":r" = "right ear", "#r" = "right ear", ".r" = "right ear", "!r" = "fake right ear", - ":l" = "left ear", "#l" = "left ear", ".l" = "left ear", "!l" = "fake left ear", + ":r" = "right ear", "#r" = "right ear", ".r" = "right ear", + ":l" = "left ear", "#l" = "left ear", ".l" = "left ear", ":i" = "intercom", "#i" = "intercom", ".i" = "intercom", ":h" = "department", "#h" = "department", ".h" = "department", + ":+" = "special", "#+" = "special", ".+" = "special", //activate radio-specific special functions ":c" = "Command", "#c" = "Command", ".c" = "Command", ":n" = "Science", "#n" = "Science", ".n" = "Science", ":m" = "Medical", "#m" = "Medical", ".m" = "Medical", ":e" = "Engineering", "#e" = "Engineering", ".e" = "Engineering", ":s" = "Security", "#s" = "Security", ".s" = "Security", ":w" = "whisper", "#w" = "whisper", ".w" = "whisper", - ":b" = "binary", "#b" = "binary", ".b" = "binary", - ":d" = "drone", "#d" = "drone", ".d" = "drone", - ":a" = "alientalk", "#a" = "alientalk", ".a" = "alientalk", ":t" = "Syndicate", "#t" = "Syndicate", ".t" = "Syndicate", ":u" = "Supply", "#u" = "Supply", ".u" = "Supply", ":z" = "Service", "#z" = "Service", ".z" = "Service", - ":g" = "changeling", "#g" = "changeling", ".g" = "changeling", + ":p" = "AI Private", "#p" = "AI Private", ".p" = "AI Private", - - ":R" = "right ear", "#R" = "right ear", ".R" = "right ear", "!R" = "fake right ear", - ":L" = "left ear", "#L" = "left ear", ".L" = "left ear", "!L" = "fake left ear", + ":R" = "right ear", "#R" = "right ear", ".R" = "right ear", + ":L" = "left ear", "#L" = "left ear", ".L" = "left ear", ":I" = "intercom", "#I" = "intercom", ".I" = "intercom", ":H" = "department", "#H" = "department", ".H" = "department", ":C" = "Command", "#C" = "Command", ".C" = "Command", @@ -28,40 +25,35 @@ var/list/department_radio_keys = list( ":E" = "Engineering", "#E" = "Engineering", ".E" = "Engineering", ":S" = "Security", "#S" = "Security", ".S" = "Security", ":W" = "whisper", "#W" = "whisper", ".W" = "whisper", - ":D" = "drone", "#D" = "drone", ".D" = "drone", - ":B" = "binary", "#B" = "binary", ".B" = "binary", - ":A" = "alientalk", "#A" = "alientalk", ".A" = "alientalk", ":T" = "Syndicate", "#T" = "Syndicate", ".T" = "Syndicate", ":U" = "Supply", "#U" = "Supply", ".U" = "Supply", ":Z" = "Service", "#Z" = "Service", ".Z" = "Service", - ":G" = "changeling", "#G" = "changeling", ".G" = "changeling" - - /* //kinda localization -- rastaf0 - //same keys as above, but on russian keyboard layout. This file uses cp1251 as encoding. - ":ê" = "right hand", "#ê" = "right hand", ".ê" = "right hand", - ":ä" = "left hand", "#ä" = "left hand", ".ä" = "left hand", - ":ø" = "intercom", "#ø" = "intercom", ".ø" = "intercom", - ":ð" = "department", "#ð" = "department", ".ð" = "department", - ":ñ" = "Command", "#ñ" = "Command", ".ñ" = "Command", - ":ò" = "Science", "#ò" = "Science", ".ò" = "Science", - ":ü" = "Medical", "#ü" = "Medical", ".ü" = "Medical", - ":ó" = "Engineering", "#ó" = "Engineering", ".ó" = "Engineering", - ":û" = "Security", "#û" = "Security", ".û" = "Security", - ":ö" = "whisper", "#ö" = "whisper", ".ö" = "whisper", - ":è" = "binary", "#è" = "binary", ".è" = "binary", - ":ô" = "alientalk", "#ô" = "alientalk", ".ô" = "alientalk", - ":å" = "Syndicate", "#å" = "Syndicate", ".å" = "Syndicate", - ":é" = "Supply", "#é" = "Supply", ".é" = "Supply", - ":ï" = "changeling", "#ï" = "changeling", ".ï" = "changeling" */ + ":P" = "AI Private", "#P" = "AI Private", ".P" = "AI Private" ) + +var/list/channel_to_radio_key = new +proc/get_radio_key_from_channel(var/channel) + var/key = channel_to_radio_key[channel] + if(!key) + for(var/radio_key in department_radio_keys) + if(department_radio_keys[radio_key] == channel) + key = radio_key + break + if(!key) + key = "" + channel_to_radio_key[channel] = key + + return key + /mob/living/proc/binarycheck() + if (istype(src, /mob/living/silicon/pai)) return - if (issilicon(src)) - return 1 + if (!ishuman(src)) return + var/mob/living/carbon/human/H = src if (H.l_ear || H.r_ear) var/obj/item/device/radio/headset/dongle @@ -72,446 +64,82 @@ var/list/department_radio_keys = list( if(!istype(dongle)) return if(dongle.translate_binary) return 1 -/mob/living/proc/hivecheck() - if (isalien(src)) return 1 - if (!ishuman(src)) return - var/mob/living/carbon/human/H = src - if (H.l_ear || H.r_ear) - var/obj/item/device/radio/headset/dongle - if(istype(H.l_ear,/obj/item/device/radio/headset)) - dongle = H.l_ear - else - dongle = H.r_ear - if(!istype(dongle)) return - if(dongle.translate_hive) return 1 - -/mob/living/say(var/message) - - /* - Formatting and sanitizing. - */ - - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) - - - /* - Sanity checking and speech failure. - */ - - if (!message) - return - - if(silent) - return - - if (stat == 2) // Dead. - return say_dead(message) - else if (stat) // Unconcious. - return - - if (src.client) - if(client.prefs.muted & MUTE_IC) - src << "\red You cannot speak in IC (muted)." - return - if (src.client.handle_spam_prevention(message,MUTE_IC)) - return - // undo last word status. - - if(ishuman(src)) - var/mob/living/carbon/human/H=src - if(H.said_last_words) - H.said_last_words=0 - - // Mute disability - if (sdisabilities & MUTE) - return - - // Muzzled. - if (istype(wear_mask, /obj/item/clothing/mask/muzzle)) - return - - // Emotes. - if (copytext(message, 1, 2) == "*" && !stat) - return emote(copytext(message, 2)) - - /* - Identity hiding. - */ - var/alt_name = "" - if (istype(src, /mob/living/carbon/human) && name != GetVoice()) - var/mob/living/carbon/human/H = src - alt_name = " (as [H.get_id_name("Unknown")])" - - /* - Now we get into the real meat of the say processing. Determining the message mode. - */ - - var/italics = 0 - var/message_range = null - var/message_mode = null - - var/datum/language/speaking = null //For use if a specific language is being spoken. - - var/braindam = getBrainLoss() - if (braindam >= 60) - if(prob(braindam/4)) - message = stutter(message) - if(prob(braindam)) - message = uppertext(message) - - // General public key. Special message handling - var/mmode - var/cprefix = "" - if(length(message) >= 2) - cprefix = copytext(message, 1, 3) - if(cprefix in department_radio_keys) - mmode = department_radio_keys[cprefix] - if (copytext(message, 1, 2) == ";" || (prob(braindam/2) && !mmode)) - message_mode = "headset" - message = copytext(message, 2) - // Begin checking for either a message mode or a language to speak. - else if (length(message) >= 2) - var/channel_prefix = copytext(message, 1, 3) - - //Check if the person is speaking a language that they know. - if(languages.len) - for(var/datum/language/L in languages) - if(lowertext(channel_prefix) == ":[L.key]") - speaking = L - break - message_mode = department_radio_keys[channel_prefix] - if (message_mode || speaking || copytext(message,1,2) == ":") - message = trim(copytext(message, 3)) - if (!(istype(src,/mob/living/carbon/human) && !isAI(src) && !isrobot(src) || istype(src,/mob/living/carbon/monkey) || istype(src, /mob/living/simple_animal/parrot) || isrobot(src) && (message_mode=="department") || isAI(src) && (message_mode=="department") || (message_mode in radiochannels))) - message_mode = null //only humans can use headsets - - if(traumatic_shock > 61 && prob(50)) - if(message_mode) - src << "You try to use your radio, but you are in too much pain." - message_mode = null //people in shock will have a high chance of not being able to speak on radio; needed since people don't instantly pass out at 100 damage. - - message = capitalize(message) - - if (!message) - return - - if (stuttering) - message = stutter(message) - - /////////////////////////////////////////////////////////// - // VIDEO KILLED THE RADIO STAR V2.0 - // - // EXPERIMENTAL CODE BY YOUR PALS AT /vg/ - /////////////////////////////////////////////////////////// - - var/list/obj/item/used_radios = new - - // Actually speaking on the radio? - var/is_speaking_radio = 0 - - // Devices selected - var/list/devices=list() - - // Select all always_talk devices - // Carbon lifeforms - //if(istype(src, /mob/living/carbon)) - for(var/obj/item/device/radio/R in contents) - if(R.always_talk) - devices += R - - //src << "Speaking on [message_mode]: [message]" - if(message_mode) - switch (message_mode) - if ("right ear") - if(iscarbon(src)) - var/mob/living/carbon/C=src - if(C:r_ear) devices += C:r_ear - message_mode="headset" - message_range = 1 - italics = 1 - - if ("left ear") - if(iscarbon(src)) - var/mob/living/carbon/C=src - if(C:l_ear) devices += C:l_ear - message_mode="headset" - message_range = 1 - italics = 1 - - // Select a headset and speak into it without actually sending a message - if ("fake") - if(iscarbon(src)) - var/mob/living/carbon/C=src - if(C:l_ear) used_radios += C:l_ear - if(C:r_ear) used_radios += C:r_ear - if(issilicon(src)) - var/mob/living/silicon/Ro=src - if(Ro:radio) devices += Ro:radio - message_range = 1 - italics = 1 - if ("fake left ear") - if(iscarbon(src)) - var/mob/living/carbon/C=src - if(C:l_ear) used_radios += C:l_ear - message_range = 1 - italics = 1 - if ("fake right ear") - if(iscarbon(src)) - var/mob/living/carbon/C=src - if(C:r_ear) used_radios += C:r_ear - message_range = 1 - italics = 1 - - if ("intercom") - for (var/obj/item/device/radio/intercom/I in view(1, null)) - devices += I - message_mode=null - message_range = 1 - italics = 1 - - //I see no reason to restrict such way of whispering - if ("whisper") - whisper(message) - return - - if ("binary") - if(robot_talk_understand || binarycheck()) - //message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) //seems redundant - robot_talk(message) - return - - if ("alientalk") - if(alien_talk_understand || hivecheck()) - //message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) //seems redundant - alien_talk(message) - return - - if ("pAI") - message_range = 1 - italics = 1 - - if("changeling") - if(mind && mind.changeling) - log_say("[key_name(src)] ([mind.changeling.changelingID]): [message]") - for(var/mob/Changeling in mob_list) - if(istype(Changeling, /mob/living/silicon)) continue //WHY IS THIS NEEDED? - if((Changeling.mind && Changeling.mind.changeling) || istype(Changeling, /mob/dead/observer)) - Changeling << "[mind.changeling.changelingID]: [message]" - else if(istype(Changeling,/mob/dead/observer) && (Changeling.client && Changeling.client.prefs.toggles & CHAT_GHOSTEARS)) - Changeling << "[mind.changeling.changelingID] (: (Follow) [message]" - return - else // headset, department channels. - if(iscarbon(src)) - var/mob/living/carbon/C=src - if(C:l_ear) devices += C:l_ear - if(C:r_ear) devices += C:r_ear - if(issilicon(src)) - if(isAI(src))//for the AI's radio. This can't be with the borg thing above due to typecasting. - var/mob/living/silicon/ai/A = src - if(A.aiRadio) - A.aiRadio.talk_into(src, message, message_mode) - used_radios += A.aiRadio - else - var/mob/living/silicon/Ro=src - if(!isAI(Ro)) - if(Ro:radio) - devices += Ro:radio - else - warning("[src] has no radio!") - message_range = 1 - italics = 1 - if(devices.len>0) - for(var/obj/item/device/radio/R in devices) - if(istype(R)) - R.talk_into(src, message, message_mode) - used_radios += R - is_speaking_radio = 1 - - ///////////////////////////////////////////////////////////////// - // - ///////////////////////////////////////////////////////////////// - - var/datum/gas_mixture/environment = loc.return_air() - if(environment) - var/pressure = environment.return_pressure() - if(pressure < SOUND_MINIMUM_PRESSURE) - italics = 1 - message_range = 1 - - var/list/listening - - listening = get_mobs_in_view(message_range, src) - var/list/onscreen = viewers() - for(var/mob/M in player_list) - if (!M.client) - continue //skip monkeys and leavers - if (istype(M, /mob/new_player)) - continue - if(M.stat == DEAD && (M.client.prefs.toggles & CHAT_GHOSTEARS) && src.client) // src.client is so that ghosts don't have to listen to mice - listening|=M +/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/italics=0, var/message_range = world.view, var/sound/speech_sound, var/sound_vol) var/turf/T = get_turf(src) - var/list/W = hear(message_range, T) - for (var/obj/O in ((W | contents)-used_radios)) - W |= O + //handle nonverbal and sign languages here + if (speaking) + if (speaking.flags & NONVERBAL) + if (prob(30)) + src.custom_emote(1, "[pick(speaking.signlang_verb)].") - for (var/mob/M in W) - W |= M.contents + if (speaking.flags & SIGNLANG) + return say_signlang(message, pick(speaking.signlang_verb), speaking) - for (var/atom/A in W) - if(istype(A, /mob/living/simple_animal/parrot)) //Parrot speech mimickry - if(A == src) - continue //Dont imitate ourselves + var/list/listening = list() + var/list/listening_obj = list() - var/mob/living/simple_animal/parrot/P = A - if(P.speech_buffer.len >= 10) - P.speech_buffer.Remove(pick(P.speech_buffer)) - P.speech_buffer.Add(message) + if(T) + //make sure the air can transmit speech - speaker's side + var/datum/gas_mixture/environment = T.return_air() + var/pressure = (environment)? environment.return_pressure() : 0 + if(pressure < SOUND_MINIMUM_PRESSURE) + message_range = 1 - if (isslime(A)) - var/mob/living/carbon/slime/S = A - if (src in S.Friends) - S.speech_buffer = list() - S.speech_buffer.Add(src) - S.speech_buffer.Add(lowertext(html_decode(message))) + if (pressure < ONE_ATMOSPHERE*0.4) //sound distortion pressure, to help clue people in that the air is thin, even if it isn't a vacuum yet + italics = 1 + sound_vol *= 0.5 //muffle the sound a bit, so it's like we're actually talking through contact - if(istype(A, /obj/)) //radio in pocket could work, radio in backpack wouldn't --rastaf0 - var/obj/O = A - spawn (0) - if(O && !istype(O.loc, /obj/item/weapon/storage)) - O.hear_talk(src, message) + var/list/hear = hear(message_range, T) + var/list/hearturfs = list() + for(var/I in hear) + if(istype(I, /mob/)) + var/mob/M = I + listening += M + hearturfs += M.locs[1] + for(var/obj/O in M.contents) + listening_obj |= O + else if(istype(I, /obj/)) + var/obj/O = I + hearturfs += O.locs[1] + listening_obj |= O - var/list/heard_a = list() // understood us - var/list/heard_b = list() // didn't understand us - - for (var/M in listening) - if(hascall(M,"say_understands")) - if (M:say_understands(src,speaking)) - heard_a += M - else - heard_b += M - else - heard_a += M + for(var/mob/M in player_list) + if (!M.client) + continue //skip monkeys and leavers + if (istype(M, /mob/new_player)) + continue + if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTEARS) && src.client) // src.client is so that ghosts don't have to listen to mice + listening |= M + continue + if(M.loc && M.locs[1] in hearturfs) + listening |= M var/speech_bubble_test = say_test(message) var/image/speech_bubble = image('icons/mob/talk.dmi',src,"h[speech_bubble_test]") spawn(30) del(speech_bubble) - for(var/mob/M in hearers(5, src)) - if(M != src && is_speaking_radio) - M:show_message("[src] talks into [used_radios.len ? used_radios[1] : "radio"]") + for(var/mob/M in listening) + M << speech_bubble + M.hear_say(message, verb, speaking, alt_name, italics, src, speech_sound, sound_vol) -/* if(message_mode == null) - var/accent = "en-us" - var/voice = "m7" - var/speed = 175 - var/pitch = 0 - var/echo = 10 - if(istype(src, /mob/living/silicon/ai)) - echo = 90 - if(istype(src, /mob/living/silicon/robot)) - echo = 60 - if(src.client && src.client.prefs) - accent = src.client.prefs.accent - voice = src.client.prefs.voice - speed = src.client.prefs.talkspeed - pitch = src.client.prefs.pitch - src:texttospeech(message, speed, pitch, accent, "+[voice]", echo)*/ - - var/rendered = null - - if (length(heard_a)) - var/message_a = say_quote(message,speaking) - - if (italics) - message_a = "[message_a]" - - var/message_ghost = "[message_a]" // bold so ghosts know the person is in view. - rendered = "[GetVoice()][alt_name] [message_a]" - var/rendered2 = null - - for (var/mob/M in heard_a) - //BEGIN TELEPORT CHANGES -/* if(message_mode == null && fexists("sound/playervoices/[src.ckey].ogg")) - if(M.client) - if(M.client.prefs) - if(M.client.prefs.sound & SOUND_VOICES) - M.playsound_local(get_turf(src), "sound/playervoices/[src.ckey].ogg", 70, 0, 5, 1)*/ - if(!istype(M, /mob/new_player)) - if(M && M.stat == DEAD) - if (M.client && M.client.prefs && (M.client.prefs.toggles & CHAT_GHOSTEARS) && M in onscreen) - rendered2 = "[GetVoice()] [alt_name] (Follow) [message_ghost]
" - else - rendered2 = "[GetVoice()] [alt_name] (Follow) [message_a]" - M:show_message(rendered2, 2) - continue - //END CHANGES - - if(hascall(M,"show_message")) - var/deaf_message = "" - var/deaf_type = 1 - if(M != src) - deaf_message = "[name][alt_name] talks but you cannot hear them." - else - deaf_message = "You cannot hear yourself!" - deaf_type = 2 // Since you should be able to hear yourself without looking - M:show_message(rendered, 2, deaf_message, deaf_type) - M << speech_bubble - - if (length(heard_b)) - - var/message_b - message_b = stars(message) - message_b = say_quote(message_b,speaking) - - if (italics) - message_b = "[message_b]" - - rendered = "[name][alt_name] [message_b]" //Voice_name isn't too useful. You'd be able to tell who was talking presumably. - var/rendered2 = null - - for (var/M in heard_b) - var/mob/MM - if(istype(M, /mob)) - MM = M - if(!istype(MM, /mob/new_player) && MM) - if(MM && MM.stat == DEAD) - rendered2 = "[voice_name] (Follow) [message_b]" - MM:show_message(rendered2, 2) - continue - if(hascall(M,"show_message")) - M:show_message(rendered, 2) - M << speech_bubble - - /* - if(M.client) - - if(!M.client.bubbles || M == src) - var/image/I = image('icons/effects/speechbubble.dmi', B, "override") - I.override = 1 - M << I - */ /* - - flick("[presay]say", B) - - if(istype(loc, /turf)) - B.loc = loc - else - B.loc = loc.loc - - spawn() - sleep(11) - del(B) - */ + for(var/obj/O in listening_obj) + spawn(0) + if(O) //It's possible that it could be deleted in the meantime. + O.hear_talk(src, message, verb, speaking) log_say("[name]/[key] : [message]") + return 1 + +/mob/living/proc/say_signlang(var/message, var/verb="gestures", var/datum/language/language) + for (var/mob/O in viewers(src, null)) + O.hear_signlang(message, verb, language, src) + return 1 /obj/effect/speech_bubble var/mob/parent /mob/living/proc/GetVoice() return name - - diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index f34da6c2e75..d5805617b5c 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -1,4 +1,33 @@ +#define AI_CHECK_WIRELESS 1 +#define AI_CHECK_RADIO 2 + var/list/ai_list = list() +var/list/ai_verbs_default = list( + /mob/living/silicon/ai/proc/ai_alerts, + /mob/living/silicon/ai/proc/announcement, + /mob/living/silicon/ai/proc/ai_call_shuttle, + /mob/living/silicon/ai/proc/ai_cancel_call, + /mob/living/silicon/ai/proc/ai_camera_track, + /mob/living/silicon/ai/proc/ai_camera_list, + /mob/living/silicon/ai/proc/ai_goto_location, + /mob/living/silicon/ai/proc/ai_remove_location, + /mob/living/silicon/ai/proc/ai_hologram_change, + /mob/living/silicon/ai/proc/ai_network_change, + /mob/living/silicon/ai/proc/ai_roster, + /mob/living/silicon/ai/proc/ai_statuschange, + /mob/living/silicon/ai/proc/ai_store_location, + /mob/living/silicon/ai/proc/checklaws, + /mob/living/silicon/ai/proc/control_integrated_radio, + /mob/living/silicon/ai/proc/core, + /mob/living/silicon/ai/proc/pick_icon, + /mob/living/silicon/ai/proc/sensor_mode, + /mob/living/silicon/ai/proc/show_laws_verb, + /mob/living/silicon/ai/proc/toggle_acceleration, + /mob/living/silicon/ai/proc/toggle_camera_light, + /mob/living/silicon/ai/proc/botcall, + /mob/living/silicon/ai/proc/change_arrival_message, + /mob/living/silicon/ai/proc/nano_crew_monitor +) //Not sure why this is necessary... /proc/AutoUpdateAI(obj/subject) @@ -11,7 +40,6 @@ var/list/ai_list = list() subject.attack_ai(M) return is_in_use - /mob/living/silicon/ai name = "AI" icon = 'icons/mob/AI.dmi'// @@ -52,8 +80,10 @@ var/list/ai_list = list() var/mob/living/silicon/ai/parent = null + var/apc_override = 0 //hack for letting the AI use its APC even when visionless var/camera_light_on = 0 //Defines if the AI toggled the light on the camera it's looking through. var/datum/trackable/track = null + var/last_paper_seen = null var/can_shunt = 1 var/last_announcement = "" var/obj/machinery/bot/Bot @@ -62,9 +92,15 @@ var/list/ai_list = list() var/obj/item/borg/sight/hud/sec/sechud = null var/obj/item/borg/sight/hud/med/healthhud = null - + var/arrivalmsg = "$name, $rank, has arrived on the station." +/mob/living/silicon/ai/proc/add_ai_verbs() + src.verbs |= ai_verbs_default + +/mob/living/silicon/ai/proc/remove_ai_verbs() + src.verbs -= ai_verbs_default + /mob/living/silicon/ai/New(loc, var/datum/ai_laws/L, var/obj/item/device/mmi/B, var/safety = 0) var/list/possibleNames = ai_names @@ -76,8 +112,8 @@ var/list/ai_list = list() possibleNames -= pickedName pickedName = null - real_name = pickedName - name = real_name + aiPDA = new/obj/item/device/pda/ai(src) + SetName(pickedName) anchored = 1 canmove = 0 density = 1 @@ -95,52 +131,42 @@ var/list/ai_list = list() verbs += /mob/living/silicon/ai/proc/show_laws_verb - aiPDA = new/obj/item/device/pda/ai(src) - aiPDA.owner = name - aiPDA.ownjob = "AI" - aiPDA.name = name + " (" + aiPDA.ownjob + ")" - aiMulti = new(src) aiRadio = new(src) + common_radio = aiRadio aiRadio.myAi = src aiCamera = new/obj/item/device/camera/siliconcam/ai_camera(src) - - if (istype(loc, /turf)) - verbs.Add(/mob/living/silicon/ai/proc/ai_network_change, \ - /mob/living/silicon/ai/proc/ai_statuschange, /mob/living/silicon/ai/proc/ai_hologram_change, \ - /mob/living/silicon/ai/proc/toggle_camera_light, /mob/living/silicon/ai/proc/botcall, /mob/living/silicon/ai/proc/control_integrated_radio, /mob/living/silicon/ai/proc/control_hud, /mob/living/silicon/ai/proc/change_arrival_message) + add_ai_verbs(src) + + //Languages + add_language("Robot Talk", 1) + add_language("Galactic Common", 1) + add_language("Sol Common", 1) + add_language("Tradeband", 1) + add_language("Gutter", 0) + add_language("Sinta'unathi", 0) + add_language("Siik'tajr", 0) + add_language("Skrellian", 0) + add_language("Vox-pidgin", 0) + add_language("Rootspeak", 0) + add_language("Trinary", 1) + add_language("Chittin", 0) + add_language("Bubblish", 0) + add_language("Clownish", 0) if(!safety)//Only used by AIize() to successfully spawn an AI. if (!B)//If there is no player/brain inside. - empty_playable_ai_cores += new/obj/structure/AIcore/deactivated(loc)//New empty terminal. + new/obj/structure/AIcore/deactivated(loc)//New empty terminal. del(src)//Delete AI. return else if (B.brainmob.mind) - if(B.alien) - B.brainmob.mind.transfer_to(src) - icon_state = "ai-alien" - verbs.Remove(,/mob/living/silicon/ai/proc/ai_call_shuttle,/mob/living/silicon/ai/proc/ai_camera_track, \ - /mob/living/silicon/ai/proc/ai_camera_list, /mob/living/silicon/ai/proc/ai_network_change, \ - /mob/living/silicon/ai/proc/ai_statuschange, /mob/living/silicon/ai/proc/ai_hologram_change, \ - /mob/living/silicon/ai/proc/toggle_camera_light,/mob/living/silicon/ai/verb/pick_icon,/mob/living/silicon/ai/proc/control_hud) - laws = new /datum/ai_laws/alienmov - else - B.brainmob.mind.transfer_to(src) + B.brainmob.mind.transfer_to(src) - src << "You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras)." - src << "To look at other parts of the station, click on yourself to get a camera menu." - src << "While observing through a camera, you can use most (networked) devices which you can see, such as computers, APCs, intercoms, doors, etc." - src << "To use something, simply click on it." - src << "Use say :b to speak to your cyborgs through binary." - if (!(ticker && ticker.mode && (mind in ticker.mode.malf_ai))) - show_laws() - src << "These laws may be changed by other players, or by you being the traitor." - - job = "AI" + on_mob_init() spawn(5) new /obj/machinery/ai_powersupply(src) @@ -154,12 +180,50 @@ var/list/ai_list = list() hud_list[IMPCHEM_HUD] = image('icons/mob/hud.dmi', src, "hudblank") hud_list[IMPTRACK_HUD] = image('icons/mob/hud.dmi', src, "hudblank") hud_list[SPECIALROLE_HUD] = image('icons/mob/hud.dmi', src, "hudblank") - hud_list[NATIONS_HUD] = image('icons/mob/hud.dmi', src, "hudblank") + hud_list[NATIONS_HUD] = image('icons/mob/hud.dmi', src, "hudblank") + + init_subsystems() ai_list += src ..() return +/mob/living/silicon/ai/proc/on_mob_init() + src << "You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras)." + src << "To look at other parts of the station, click on yourself to get a camera menu." + src << "While observing through a camera, you can use most (networked) devices which you can see, such as computers, APCs, intercoms, doors, etc." + src << "To use something, simply click on it." + src << "Use say :b to speak to your cyborgs through binary. Use say :h to speak from an active holopad." + src << "For department channels, use the following say commands:" + + var/radio_text = "" + for(var/i = 1 to common_radio.channels.len) + var/channel = common_radio.channels[i] + var/key = get_radio_key_from_channel(channel) + radio_text += "[key] - [channel]" + if(i != common_radio.channels.len) + radio_text += ", " + + src << radio_text + + if (!(ticker && ticker.mode && (mind in ticker.mode.malf_ai))) + show_laws() + src << "These laws may be changed by other players, or by you being the traitor." + + job = "AI" + +/mob/living/silicon/ai/proc/SetName(pickedName as text) + real_name = pickedName + name = pickedName + if(eyeobj) + eyeobj.name = "[pickedName] (AI Eye)" + + // Set ai pda name + if(aiPDA) + aiPDA.ownjob = "AI" + aiPDA.owner = pickedName + aiPDA.name = pickedName + " (" + aiPDA.ownjob + ")" + /mob/living/silicon/ai/Destroy() ai_list -= src ..() @@ -196,7 +260,7 @@ var/list/ai_list = list() if(powered_ai.anchored) use_power = 2 -/mob/living/silicon/ai/verb/pick_icon() +/mob/living/silicon/ai/proc/pick_icon() set category = "AI Commands" set name = "Set AI Core Display" if(stat || aiRestorePowerRoutine) @@ -260,6 +324,9 @@ var/list/ai_list = list() /mob/living/silicon/ai/proc/ai_alerts() + set name = "Show Alerts" + set category = "AI Commands" + var/dat = "Current Station Alerts\n" dat += "Close

" for (var/cat in alarms) @@ -294,20 +361,26 @@ var/list/ai_list = list() // this verb lets the ai see the stations manifest /mob/living/silicon/ai/proc/ai_roster() + set name = "Show Crew Manifest" + set category = "AI Commands" show_station_manifest() /mob/living/silicon/ai/proc/ai_call_shuttle() + set name = "Call Emergency Shuttle" + set category = "AI Commands" + if(src.stat == 2) src << "You can't call the shuttle because you are dead!" return - if(istype(usr,/mob/living/silicon/ai)) - var/mob/living/silicon/ai/AI = src - if(AI.control_disabled) - usr << "Wireless control is disabled!" - return + + if(check_unable(AI_CHECK_WIRELESS)) + return var/confirm = alert("Are you sure you want to call the shuttle?", "Confirm Shuttle Call", "Yes", "No") + if(check_unable(AI_CHECK_WIRELESS)) + return + if(confirm == "Yes") call_shuttle_proc(src) @@ -316,38 +389,57 @@ var/list/ai_list = list() var/obj/machinery/computer/communications/C = locate() in machines if(C) C.post_status("shuttle") - return +/mob/living/silicon/ai/proc/ai_cancel_call() + set name = "Recall Emergency Shuttle" + set category = "AI Commands" + + if(src.stat == 2) + src << "You can't send the shuttle back because you are dead!" + return + + if(check_unable(AI_CHECK_WIRELESS)) + return + + var/confirm = alert("Are you sure you want to recall the shuttle?", "Confirm Shuttle Recall", "Yes", "No") + + if(check_unable(AI_CHECK_WIRELESS)) + return + + if(confirm == "Yes") + cancel_call_proc(src) + /mob/living/silicon/ai/cancel_camera() src.view_core() /mob/living/silicon/ai/verb/toggle_anchor() - set category = "AI Commands" - set name = "Toggle Floor Bolts" - if(!isturf(loc)) // if their location isn't a turf - return // stop - anchored = !anchored // Toggles the anchor + set category = "AI Commands" + set name = "Toggle Floor Bolts" - src << "[anchored ? "You are now anchored." : "You are now unanchored."]" - // the message in the [] will change depending whether or not the AI is anchored + if(!isturf(loc)) // if their location isn't a turf + return // stop + + anchored = !anchored // Toggles the anchor + + src << "[anchored ? "You are now anchored." : "You are now unanchored."]" /mob/living/silicon/ai/update_canmove() return 0 +/mob/living/silicon/ai/proc/announcement() + set name = "Announcement" + set desc = "Create a vocal announcement by typing in the available words to create a sentence." + set category = "AI Commands" -/mob/living/silicon/ai/proc/ai_cancel_call() - set category = "Malfunction" if(src.stat == 2) - src << "You can't send the shuttle back because you are dead!" + src << "You can't call make an announcement because you are dead!" return - if(istype(usr,/mob/living/silicon/ai)) - var/mob/living/silicon/ai/AI = src - if(AI.control_disabled) - src << "Wireless control is disabled!" - return - cancel_call_proc(src) - return + + if(check_unable(AI_CHECK_WIRELESS | AI_CHECK_RADIO)) + return + + ai_announcement() /mob/living/silicon/ai/check_eye(var/mob/user as mob) if (!current) @@ -405,9 +497,12 @@ var/list/ai_list = list() unset_machine() src << browse(null, t1) if (href_list["switchcamera"]) - switchCamera(locate(href_list["switchcamera"])) in cameranet.viewpoints + switchCamera(locate(href_list["switchcamera"])) in cameranet.cameras if (href_list["showalerts"]) ai_alerts() + if(href_list["show_paper"]) + if(last_paper_seen) + src << browse(last_paper_seen, "window=show_paper") //Carn: holopad requests if (href_list["jumptoholopad"]) var/obj/machinery/hologram/holopad/H = locate(href_list["jumptoholopad"]) @@ -449,9 +544,11 @@ var/list/ai_list = list() if (href_list["track"]) var/mob/target = locate(href_list["track"]) in mob_list - var/mob/living/silicon/ai/A = locate(href_list["track2"]) in mob_list - if(A && target) - A.ai_actual_track(target) + + if(target && (!istype(target, /mob/living/carbon/human) || html_decode(href_list["trackname"]) == target:get_face_name())) + ai_actual_track(target) + else + src << "\red System error. Cannot locate [html_decode(href_list["trackname"])]." return if (href_list["trackbot"]) @@ -485,7 +582,7 @@ var/list/ai_list = list() if(A && target) A.cameraFollow = target - A << text("Now tracking [] on camera.", target.name) + A << "Now tracking [target.name] on camera." if (usr.machine == null) usr.machine = usr @@ -514,6 +611,7 @@ var/list/ai_list = list() updatehealth() return 2 + /mob/living/silicon/ai/attack_alien(mob/living/carbon/alien/humanoid/M as mob) if (!ticker) M << "You cannot attack people before the game has started." @@ -526,38 +624,35 @@ var/list/ai_list = list() switch(M.a_intent) if ("help") - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\blue [M] caresses [src]'s plating with its scythe like arm."), 1) + visible_message("[M] caresses [src]'s plating with its scythe like arm.") else //harm + M.do_attack_animation(src) var/damage = rand(10, 20) if (prob(90)) playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has slashed at []!", M, src), 1) + visible_message("[M] has slashed at [src]!",\ + "[M] has slashed at [src]!") if(prob(8)) flick("noise", flash) adjustBruteLoss(damage) updatehealth() else playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] took a swipe at []!", M, src), 1) + visible_message("[M] took a swipe at [src]!", \ + "[M] took a swipe at [src]!") + return /mob/living/silicon/ai/attack_animal(mob/living/simple_animal/M as mob) if(M.melee_damage_upper == 0) M.emote("[M.friendly] [src]") else + M.do_attack_animation(src) if(M.attack_sound) playsound(loc, M.attack_sound, 50, 1, 1) - for(var/mob/O in viewers(src, null)) - O.show_message("\red [M] [M.attacktext] [src]!", 1) - M.attack_log += text("\[[time_stamp()]\] attacked [src.name] ([src.ckey])") - src.attack_log += text("\[[time_stamp()]\] was attacked by [M.name] ([M.ckey])") + visible_message("[M] [M.attacktext] [src]!") + add_logs(M, src, "attacked", admin=0) var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) adjustBruteLoss(damage) updatehealth() @@ -580,18 +675,17 @@ var/list/ai_list = list() src << "Critical error. System offline." return - if(control_disabled) - src << "Wireless communication is disabled." + if(check_unable(AI_CHECK_WIRELESS | AI_CHECK_RADIO)) return - var/turf/ai_current_turf = get_turf(src) - var/ai_Zlevel = ai_current_turf.z + + var/ai_allowed_Zlevel = list(1,3,5) var/d var/area/bot_area d += "Query network status
" d += "
" for (Bot in aibots) - if(Bot.z == ai_Zlevel && !Bot.remote_disabled) //Only non-emagged bots on the same Z-level are detected! + if((Bot.z in ai_allowed_Zlevel) && !Bot.remote_disabled) //Only non-emagged bots on the allowed Z-level are detected! bot_area = get_area(Bot) d += "" //If the bot is on, it will display the bot's current mode status. If the bot is not mode, it will just report "Idle". "Inactive if it is not on at all. @@ -630,8 +724,6 @@ var/list/ai_list = list() /mob/living/silicon/ai/proc/switchCamera(var/obj/machinery/camera/C) - src.cameraFollow = null - if (!C || stat == 2) //C.can_use()) return 0 @@ -705,26 +797,31 @@ var/list/ai_list = list() set category = "AI Commands" set name = "Jump To Network" unset_machine() - src.cameraFollow = null var/cameralist[0] + if(check_unable()) + return + if(usr.stat == 2) usr << "You can't change your camera network because you are dead!" return var/mob/living/silicon/ai/U = usr - for (var/obj/machinery/camera/C in cameranet.viewpoints) + for (var/obj/machinery/camera/C in cameranet.cameras) if(!C.can_use()) continue - var/list/tempnetwork = difflist(C.network,RESTRICTED_CAMERA_NETWORKS,1) + var/list/tempnetwork = difflist(C.network,restricted_camera_networks,1) if(tempnetwork.len) for(var/i in tempnetwork) cameralist[i] = i var/old_network = network network = input(U, "Which network would you like to view?") as null|anything in cameralist + if(check_unable()) + return + if(!U.eyeobj) U.view_core() return @@ -732,7 +829,7 @@ var/list/ai_list = list() if(isnull(network)) network = old_network // If nothing is selected else - for(var/obj/machinery/camera/C in cameranet.viewpoints) + for(var/obj/machinery/camera/C in cameranet.cameras) if(!C.can_use()) continue if(network in C.network) @@ -755,8 +852,16 @@ var/list/ai_list = list() if(usr.stat == 2) usr <<"You cannot change your emotional status because you are dead!" return + + if(check_unable()) + return + var/list/ai_emotions = list("Very Happy", "Happy", "Neutral", "Unsure", "Confused", "Sad", "BSOD", "Blank", "Problems?", "Awesome", "Facepalm", "Friend Computer") var/emote = input("Please, select a status!", "AI Status", null, null) in ai_emotions + + if(check_unable()) + return + for (var/obj/machinery/M in machines) //change status if(istype(M, /obj/machinery/ai_status_display)) var/obj/machinery/ai_status_display/AISD = M @@ -777,6 +882,9 @@ var/list/ai_list = list() set desc = "Change the default hologram available to AI to something else." set category = "AI Commands" + if(check_unable()) + return + var/input if(alert("Would you like to select a hologram based on a crew member or switch to unique avatar?",,"Crew Member","Unique")=="Crew Member") @@ -831,6 +939,9 @@ var/list/ai_list = list() if(stat != CONSCIOUS) return + if(check_unable()) + return + camera_light_on = !camera_light_on src << "Camera lights [camera_light_on ? "activated" : "deactivated"]." if(!camera_light_on) @@ -840,17 +951,17 @@ var/list/ai_list = list() else lightNearbyCamera() -/mob/living/silicon/ai/proc/control_hud() +/mob/living/silicon/ai/proc/sensor_mode() set name = "Set Sensor Augmentation" set desc = "Augment visual feed with internal sensor overlays." set category = "AI Commands" toggle_sensor_mode() - + /mob/living/silicon/ai/proc/change_arrival_message() set name = "Set Arrival Message" set desc = "Change the message that's transmitted when a new crew member arrives on station." set category = "AI Commands" - + var/newmsg = input("What would you like the arrival message to be? Use $name to substitute the crew member's name, and use $rank to substitute the crew member's rank.", "Change Arrival Message", arrivalmsg) as text if(newmsg != arrivalmsg) arrivalmsg = newmsg @@ -881,7 +992,7 @@ var/list/ai_list = list() camera_light_on = world.timeofday + 1 * 20 // Update the light every 2 seconds. -/mob/living/silicon/ai/attackby(obj/item/weapon/W as obj, mob/user as mob) +/mob/living/silicon/ai/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/wrench)) if(anchored) user.visible_message("\blue \The [user] starts to unbolt \the [src] from the plating...") @@ -908,6 +1019,79 @@ var/list/ai_list = list() set desc = "Allows you to change settings of your radio." set category = "AI Commands" + if(check_unable(AI_CHECK_RADIO)) + return + src << "Accessing Subspace Transceiver control..." if (src.aiRadio) src.aiRadio.interact(src) + + +/mob/living/silicon/ai/proc/open_nearest_door(mob/living/target as mob) + if(!istype(target)) return + spawn(0) + if(istype(target, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = target + if(H.wear_id && istype(H.wear_id.GetID(), /obj/item/weapon/card/id/syndicate)) + src << "Unable to locate an airlock" + return + if(H.wear_id && istype(H.wear_id.GetID(), /obj/item/weapon/card/id/syndicate)) + src << "Unable to locate an airlock" + return + if(istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja) && (H.head.flags & NODROP)) + src << "Unable to locate an airlock" + return + if(H.digitalcamo) + src << "Unable to locate an airlock" + return + if (!near_camera(target)) + src << "Target is not near any active cameras." + return + var/obj/machinery/door/airlock/tobeopened + var/dist = -1 + for(var/obj/machinery/door/airlock/D in range(3,target)) + if(!D.density) continue + if(dist < 0) + dist = get_dist(D, target) + //world << dist + tobeopened = D + else + if(dist > get_dist(D, target)) + dist = get_dist(D, target) + //world << dist + tobeopened = D + //world << "found [tobeopened.name] closer" + else + //world << "[D.name] not close enough | [get_dist(D, target)] | [dist]" + if(tobeopened) + switch(alert(src, "Do you want to open \the [tobeopened] for [target]?","Doorknob_v2a.exe","Yes","No")) + if("Yes") + var/nhref = "src=\ref[tobeopened];aiEnable=7" + tobeopened.Topic(nhref, params2list(nhref), tobeopened, 1) + src << "\blue You've opened \the [tobeopened] for [target]." + if("No") + src << "\red You deny the request." + else + src << "\red You've failed to open an airlock for [target]" + return + + +/mob/living/silicon/ai/proc/check_unable(var/flags = 0) + if(stat == DEAD) + usr << "\red You are dead!" + return 1 + + if((flags & AI_CHECK_WIRELESS) && src.control_disabled) + usr << "\red Wireless control is disabled!" + return 1 + if((flags & AI_CHECK_RADIO) && src.aiRadio.disabledAi) + src << "\red System Error - Transceiver Disabled!" + return 1 + return 0 + +/mob/living/silicon/ai/proc/is_in_chassis() + return istype(loc, /turf) + +#undef AI_CHECK_WIRELESS +#undef AI_CHECK_RADIO + diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm index c9541858467..dfa05ddc5d0 100644 --- a/code/modules/mob/living/silicon/ai/death.dm +++ b/code/modules/mob/living/silicon/ai/death.dm @@ -15,21 +15,21 @@ var/callshuttle = 0 for(var/obj/machinery/computer/communications/commconsole in world) - if(commconsole.z == 2) + if((commconsole.z in config.admin_levels)) continue if(istype(commconsole.loc,/turf)) break callshuttle++ for(var/obj/item/weapon/circuitboard/communications/commboard in world) - if(commboard.z == 2) + if((commboard.z in config.admin_levels)) continue if(istype(commboard.loc,/turf) || istype(commboard.loc,/obj/item/weapon/storage)) break callshuttle++ for(var/mob/living/silicon/ai/shuttlecaller in player_list) - if(shuttlecaller.z == 2) + if((shuttlecaller.z in config.admin_levels)) continue if(!shuttlecaller.stat && shuttlecaller.client && istype(shuttlecaller.loc,/turf)) break diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm index b0caf3b4a69..584af962874 100644 --- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm +++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm @@ -1,25 +1,156 @@ -/datum/visibility_network/cameras - ChunkType = /datum/visibility_chunk/camera +// CAMERA NET +// +// The datum containing all the chunks. -/datum/visibility_network/cameras/getViewpointFromMob(var/mob/currentMob) - var/mob/living/silicon/robot/currentRobot=currentMob - if(currentRobot) - return currentRobot.camera - return FALSE +var/datum/cameranet/cameranet = new() -/datum/visibility_network/cameras/validViewpoint(var/viewpoint) - var/obj/machinery/camera/c = viewpoint - if (!c) - return FALSE - return c.can_use() +/datum/cameranet + // The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Del(). + var/list/cameras = list() + var/cameras_unsorted = 1 + // The chunks of the map, mapping the areas that the cameras can see. + var/list/chunks = list() + var/ready = 0 +/datum/cameranet/proc/process_sort() + if(cameras_unsorted) + cameras = dd_sortedObjectList(cameras) + cameras_unsorted = 0 -// adding some indirection so that I don't have to edit a ton of files -/datum/visibility_network/cameras/proc/addCamera(var/camera) - return addViewpoint(camera) +// Checks if a chunk has been Generated in x, y, z. +/datum/cameranet/proc/chunkGenerated(x, y, z) + x &= ~0xf + y &= ~0xf + var/key = "[x],[y],[z]" + return (chunks[key]) -/datum/visibility_network/cameras/proc/removeCamera(var/camera) - return removeViewpoint(camera) +// Returns the chunk in the x, y, z. +// If there is no chunk, it creates a new chunk and returns that. +/datum/cameranet/proc/getCameraChunk(x, y, z) + x &= ~0xf + y &= ~0xf + var/key = "[x],[y],[z]" + if(!chunks[key]) + chunks[key] = new /datum/camerachunk(null, x, y, z) -/datum/visibility_network/cameras/proc/checkCameraVis(var/atom/target) - return checkCanSee(target) + return chunks[key] + +// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set. + +/datum/cameranet/proc/visibility(mob/aiEye/ai) + // 0xf = 15 + var/x1 = max(0, ai.x - 16) & ~0xf + var/y1 = max(0, ai.y - 16) & ~0xf + var/x2 = min(world.maxx, ai.x + 16) & ~0xf + var/y2 = min(world.maxy, ai.y + 16) & ~0xf + + var/list/visibleChunks = list() + + for(var/x = x1; x <= x2; x += 16) + for(var/y = y1; y <= y2; y += 16) + visibleChunks += getCameraChunk(x, y, ai.z) + + var/list/remove = ai.visibleCameraChunks - visibleChunks + var/list/add = visibleChunks - ai.visibleCameraChunks + + for(var/chunk in remove) + var/datum/camerachunk/c = chunk + c.remove(ai) + + for(var/chunk in add) + var/datum/camerachunk/c = chunk + c.add(ai) + +// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. + +/datum/cameranet/proc/updateVisibility(atom/A, var/opacity_check = 1) + + if(!ticker || (opacity_check && !A.opacity)) + return + majorChunkChange(A, 2) + +/datum/cameranet/proc/updateChunk(x, y, z) + // 0xf = 15 + if(!chunkGenerated(x, y, z)) + return + var/datum/camerachunk/chunk = getCameraChunk(x, y, z) + chunk.hasChanged() + +// Removes a camera from a chunk. + +/datum/cameranet/proc/removeCamera(obj/machinery/camera/c) + if(c.can_use()) + majorChunkChange(c, 0) + +// Add a camera to a chunk. + +/datum/cameranet/proc/addCamera(obj/machinery/camera/c) + if(c.can_use()) + majorChunkChange(c, 1) + +// Used for Cyborg cameras. Since portable cameras can be in ANY chunk. + +/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/c) + if(c.can_use()) + majorChunkChange(c, 1) + //else + // majorChunkChange(c, 0) + +// Never access this proc directly!!!! +// This will update the chunk and all the surrounding chunks. +// It will also add the atom to the cameras list if you set the choice to 1. +// Setting the choice to 0 will remove the camera from the chunks. +// If you want to update the chunks around an object, without adding/removing a camera, use choice 2. + +/datum/cameranet/proc/majorChunkChange(atom/c, var/choice) + // 0xf = 15 + if(!c) + return + + var/turf/T = get_turf(c) + if(T) + var/x1 = max(0, T.x - 8) & ~0xf + var/y1 = max(0, T.y - 8) & ~0xf + var/x2 = min(world.maxx, T.x + 8) & ~0xf + var/y2 = min(world.maxy, T.y + 8) & ~0xf + + //world << "X1: [x1] - Y1: [y1] - X2: [x2] - Y2: [y2]" + + for(var/x = x1; x <= x2; x += 16) + for(var/y = y1; y <= y2; y += 16) + if(chunkGenerated(x, y, T.z)) + var/datum/camerachunk/chunk = getCameraChunk(x, y, T.z) + if(choice == 0) + // Remove the camera. + chunk.cameras -= c + else if(choice == 1) + // You can't have the same camera in the list twice. + chunk.cameras |= c + chunk.hasChanged() + +// Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0. + +/datum/cameranet/proc/checkCameraVis(mob/living/target as mob) + + // 0xf = 15 + var/turf/position = get_turf(target) + return checkTurfVis(position) + +/datum/cameranet/proc/checkTurfVis(var/turf/position) + var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z) + if(chunk) + if(chunk.changed) + chunk.hasChanged(1) // Update now, no matter if it's visible or not. + if(chunk.visibleTurfs[position]) + return 1 + return 0 + +// Debug verb for VVing the chunk that the turf is in. +/* +/turf/verb/view_chunk() + set src in world + + if(cameranet.chunkGenerated(x, y, z)) + var/datum/camerachunk/chunk = cameranet.getCameraChunk(x, y, z) + usr.client.debug_variables(chunk) +*/ \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index ba4e7892f57..fda4ef2f78e 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -1,23 +1,168 @@ -/datum/visibility_chunk/camera +#define UPDATE_BUFFER 25 // 2.5 seconds -/datum/visibility_chunk/camera/validViewpoint(var/viewpoint) - var/obj/machinery/camera/c = viewpoint - if(!c) - return FALSE - if(!c.can_use()) - return FALSE - var/turf/point = locate(src.x + 8, src.y + 8, src.z) - if(get_dist(point, c) > 24) - return FALSE - return TRUE +// CAMERA CHUNK +// +// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed. +// Allows the AI Eye to stream these chunks and know what it can and cannot see. +/datum/camerachunk + var/list/obscuredTurfs = list() + var/list/visibleTurfs = list() + var/list/obscured = list() + var/list/cameras = list() + var/list/turfs = list() + var/list/seenby = list() + var/visible = 0 + var/changed = 0 + var/updating = 0 + var/x = 0 + var/y = 0 + var/z = 0 -/datum/visibility_chunk/camera/getVisibleTurfsForViewpoint(var/viewpoint) - var/obj/machinery/camera/c = viewpoint - return c.can_see() +// Add an AI eye to the chunk, then update if changed. +/datum/camerachunk/proc/add(mob/aiEye/ai) + if(!ai.ai) + return + ai.visibleCameraChunks += src + if(ai.ai.client) + ai.ai.client.images += obscured + visible++ + seenby += ai + if(changed && !updating) + update() + +// Remove an AI eye from the chunk, then update if changed. + +/datum/camerachunk/proc/remove(mob/aiEye/ai) + if(!ai.ai) + return + ai.visibleCameraChunks -= src + if(ai.ai.client) + ai.ai.client.images -= obscured + seenby -= ai + if(visible > 0) + visible-- + +// Called when a chunk has changed. I.E: A wall was deleted. + +/datum/camerachunk/proc/visibilityChanged(turf/loc) + if(!visibleTurfs[loc]) + return + hasChanged() + +// Updates the chunk, makes sure that it doesn't update too much. If the chunk isn't being watched it will +// instead be flagged to update the next time an AI Eye moves near it. + +/datum/camerachunk/proc/hasChanged(var/update_now = 0) + if(visible || update_now) + if(!updating) + updating = 1 + spawn(UPDATE_BUFFER) // Batch large changes, such as many doors opening or closing at once + update() + updating = 0 + else + changed = 1 + +// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists. + +/datum/camerachunk/proc/update() + + set background = 1 + + var/list/newVisibleTurfs = list() + + for(var/camera in cameras) + var/obj/machinery/camera/c = camera + + if(!c) + continue + + if(!c.can_use()) + continue + + var/turf/point = locate(src.x + 8, src.y + 8, src.z) + if(get_dist(point, c) > 24) + continue + + for(var/turf/t in c.can_see()) + newVisibleTurfs[t] = t + + // Removes turf that isn't in turfs. + newVisibleTurfs &= turfs + + var/list/visAdded = newVisibleTurfs - visibleTurfs + var/list/visRemoved = visibleTurfs - newVisibleTurfs + + visibleTurfs = newVisibleTurfs + obscuredTurfs = turfs - newVisibleTurfs + + for(var/turf in visAdded) + var/turf/t = turf + if(t.obscured) + obscured -= t.obscured + for(var/eye in seenby) + var/mob/aiEye/m = eye + if(!m || !m.ai) + continue + if(m.ai.client) + m.ai.client.images -= t.obscured + + for(var/turf in visRemoved) + var/turf/t = turf + if(obscuredTurfs[t]) + if(!t.obscured) + t.obscured = image('icons/effects/cameravis.dmi', t, "black", 15) + + obscured += t.obscured + for(var/eye in seenby) + var/mob/aiEye/m = eye + if(!m || !m.ai) + seenby -= m + continue + if(m.ai.client) + m.ai.client.images += t.obscured + +// Create a new camera chunk, since the chunks are made as they are needed. + +/datum/camerachunk/New(loc, x, y, z) + + // 0xf = 15 + x &= ~0xf + y &= ~0xf + + src.x = x + src.y = y + src.z = z -/datum/visibility_chunk/camera/findNearbyViewpoints() for(var/obj/machinery/camera/c in range(16, locate(x + 8, y + 8, z))) if(c.can_use()) - viewpoints += c + cameras += c + + for(var/turf/t in range(10, locate(x + 8, y + 8, z))) + if(t.x >= x && t.y >= y && t.x < x + 16 && t.y < y + 16) + turfs[t] = t + + for(var/camera in cameras) + var/obj/machinery/camera/c = camera + if(!c) + continue + + if(!c.can_use()) + continue + + for(var/turf/t in c.can_see()) + visibleTurfs[t] = t + + // Removes turf that isn't in turfs. + visibleTurfs &= turfs + + obscuredTurfs = turfs - visibleTurfs + + for(var/turf in obscuredTurfs) + var/turf/t = turf + if(!t.obscured) + t.obscured = image('icons/effects/cameravis.dmi', t, "black", 15) + obscured += t.obscured + +#undef UPDATE_BUFFER \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index c2c23b02188..50b60912107 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -1,6 +1,6 @@ // AI EYE // -// A mob that the AI controls to look around the station with. +// An invisible (no icon) mob that the AI controls to look around the station with. // It streams chunks as it moves around, which will show it what the AI can and cannot see. /mob/aiEye @@ -8,23 +8,34 @@ icon = 'icons/mob/AI.dmi' icon_state = "eye" alpha = 127 + var/list/visibleCameraChunks = list() var/mob/living/silicon/ai/ai = null density = 0 status_flags = GODMODE // You can't damage it. mouse_opacity = 0 see_in_dark = 7 - invisibility = INVISIBILITY_AI_EYE + invisibility = SEE_INVISIBLE_OBSERVER + var/ghostimage = null /mob/aiEye/New() + ghostimage = image(src.icon,src,src.icon_state) + ghost_darkness_images |= ghostimage //so ghosts can see the blob cursor when they disable darkness + updateallghostimages() ..() - visibility_interface = new /datum/visibility_interface/ai_eye(src) + +/mob/aiEye/Destroy() + if (ghostimage) + ghost_darkness_images -= ghostimage + qdel(ghostimage) + ghostimage = null; + updateallghostimages() // Movement code. Returns 0 to stop air movement from moving it. /mob/aiEye/Move() return 0 // Hide popout menu verbs -/mob/aiEye/examine() +/mob/aiEye/examine(atom/A as mob|obj|turf in view()) set popup_menu = 0 set src = usr.contents return 0 @@ -41,11 +52,15 @@ // Use this when setting the aiEye's location. // It will also stream the chunk that the new loc is in. +/mob/aiEye/setLoc(var/T, var/cancel_tracking = 1) -/mob/aiEye/setLoc(var/T) if(ai) if(!isturf(ai.loc)) return + + if(cancel_tracking) + ai.ai_cancel_tracking() + T = get_turf(T) loc = T cameranet.visibility(src) @@ -55,9 +70,12 @@ if(ai.holo) ai.holo.move_hologram() +/mob/aiEye/proc/getLoc() -/mob/aiEye/Move() - return 0 + if(ai) + if(!isturf(ai.loc) || !ai.client) + return + return ai.eyeobj.loc // AI MOVEMENT @@ -70,7 +88,6 @@ var/acceleration = 1 var/obj/machinery/hologram/holopad/holo = null - // Intiliaze the eye by assigning it's "ai" variable to us. Then set it's loc to us. /mob/living/silicon/ai/New() ..() @@ -79,7 +96,7 @@ spawn(5) eyeobj.loc = src.loc -/mob/living/silicon/ai/Destroy() +/mob/living/silicon/ai/Del() eyeobj.ai = null del(eyeobj) // No AI, no Eye ..() @@ -88,9 +105,7 @@ if(istype(usr, /mob/living/silicon/ai)) var/mob/living/silicon/ai/AI = usr if(AI.eyeobj && AI.client.eye == AI.eyeobj) - AI.cameraFollow = null - if (isturf(src.loc) || isturf(src)) - AI.eyeobj.setLoc(src) + AI.eyeobj.setLoc(src) // This will move the AIEye. It will also cause lights near the eye to light up, if toggled. // This is handled in the proc below this one. @@ -114,35 +129,36 @@ else user.sprint = initial - user.cameraFollow = null - //user.unset_machine() //Uncomment this if it causes problems. //user.lightNearbyCamera() // Return to the Core. -/mob/living/silicon/ai/proc/view_core() +/mob/living/silicon/ai/proc/core() + set category = "AI Commands" + set name = "AI Core" + + view_core() + + +/mob/living/silicon/ai/proc/view_core() current = null - cameraFollow = null unset_machine() - if(src.eyeobj && src.loc) - src.eyeobj.z = src.z - src.eyeobj.loc = src.loc - else + if(!src.eyeobj) src << "ERROR: Eyeobj not found. Creating new eye..." src.eyeobj = new(src.loc) src.eyeobj.ai = src - src.eyeobj.name = "[src.name] (AI Eye)" // Give it a name + src.SetName(src.name) if(client && client.eye) client.eye = src - - for(var/datum/visibility_chunk/camera/c in eyeobj.visibility_interface.visible_chunks) + for(var/datum/camerachunk/c in eyeobj.visibleCameraChunks) c.remove(eyeobj) + src.eyeobj.setLoc(src) -/mob/living/silicon/ai/verb/toggle_acceleration() +/mob/living/silicon/ai/proc/toggle_acceleration() set category = "AI Commands" set name = "Toggle Camera Acceleration" diff --git a/code/modules/mob/living/silicon/ai/freelook/read_me.dm b/code/modules/mob/living/silicon/ai/freelook/read_me.dm index e71b0903b85..53e68ff1377 100644 --- a/code/modules/mob/living/silicon/ai/freelook/read_me.dm +++ b/code/modules/mob/living/silicon/ai/freelook/read_me.dm @@ -20,7 +20,7 @@ HOW IT WORKS It works by first creating a camera network datum. Inside of this camera network are "chunks" (which will be - explained later) and "cameras". The cameras list is kept up to date by obj/machinery/camera/New() and Destroy(). + explained later) and "cameras". The cameras list is kept up to date by obj/machinery/camera/New() and Del(). Next the camera network has chunks. These chunks are a 16x16 tile block of turfs and cameras contained inside the chunk. These turfs are then sorted out based on what the cameras can and cannot see. If none of the cameras can see the turf, inside @@ -43,7 +43,7 @@ WHERE IS EVERYTHING? - cameraNetwork.dm = Everything about the cameraNetwork datum. + cameranet.dm = Everything about the cameranet datum. chunk.dm = Everything about the chunk datum. eye.dm = Everything about the AI and the AIEye. updating.dm = Everything about triggers that will update chunks. diff --git a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm index 775d8864751..9458a768633 100644 --- a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm +++ b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm @@ -1,3 +1,80 @@ +#define BORG_CAMERA_BUFFER 30 + +//UPDATE TRIGGERS, when the chunk (and the surrounding chunks) should update. + +// TURFS + +/turf + var/image/obscured + +/turf/proc/visibilityChanged() + if(ticker) + cameranet.updateVisibility(src) + +/turf/simulated/Del() + visibilityChanged() + ..() + +/turf/simulated/New() + ..() + visibilityChanged() + + + +// STRUCTURES + +/obj/structure/Del() + if(ticker) + cameranet.updateVisibility(src) + ..() + +/obj/structure/New() + ..() + if(ticker) + cameranet.updateVisibility(src) + +// EFFECTS + +/obj/effect/Del() + if(ticker) + cameranet.updateVisibility(src) + ..() + +/obj/effect/New() + ..() + if(ticker) + cameranet.updateVisibility(src) + + +// DOORS + +// Simply updates the visibility of the area when it opens/closes/destroyed. +/obj/machinery/door/update_nearby_tiles(need_rebuild) + . = ..(need_rebuild) + // Glass door glass = 1 + // don't check then? + if(!glass && cameranet) + cameranet.updateVisibility(src, 0) + + +// ROBOT MOVEMENT + +// Update the portable camera everytime the Robot moves. +// This might be laggy, comment it out if there are problems. +/mob/living/silicon/robot/var/updating = 0 + +/mob/living/silicon/robot/Move() + var/oldLoc = src.loc + . = ..() + if(.) + if(src.camera && src.camera.network.len) + if(!updating) + updating = 1 + spawn(BORG_CAMERA_BUFFER) + if(oldLoc != src.loc) + cameranet.updatePortableCamera(src.camera) + updating = 0 + // CAMERA // An addition to deactivate which removes/adds the camera from the chunk list based on if it works or not. @@ -5,23 +82,29 @@ /obj/machinery/camera/deactivate(user as mob, var/choice = 1) ..(user, choice) if(src.can_use()) - cameranet.addViewpoint(src) + cameranet.addCamera(src) else src.SetLuminosity(0) - cameranet.removeViewpoint(src) + cameranet.removeCamera(src) /obj/machinery/camera/New() ..() - cameranet.viewpoints += src //Camera must be added to global list of all cameras no matter what... - var/list/open_networks = difflist(network,RESTRICTED_CAMERA_NETWORKS) //...but if all of camera's networks are restricted, it only works for specific camera consoles. + //Camera must be added to global list of all cameras no matter what... + if(cameranet.cameras_unsorted || !ticker) + cameranet.cameras += src + cameranet.cameras_unsorted = 1 + else + dd_insertObjectList(cameranet.cameras, src) + + var/list/open_networks = difflist(network,restricted_camera_networks) //...but if all of camera's networks are restricted, it only works for specific camera consoles. if(open_networks.len) //If there is at least one open network, chunk is available for AI usage. - cameranet.addViewpoint(src) + cameranet.addCamera(src) /obj/machinery/camera/Del() - cameranet.viewpoints -= src - var/list/open_networks = difflist(network,RESTRICTED_CAMERA_NETWORKS) + cameranet.cameras -= src + var/list/open_networks = difflist(network,restricted_camera_networks) if(open_networks.len) - cameranet.removeViewpoint(src) + cameranet.removeCamera(src) ..() #undef BORG_CAMERA_BUFFER \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/freelook/visibility_interface.dm b/code/modules/mob/living/silicon/ai/freelook/visibility_interface.dm deleted file mode 100644 index b55598c6090..00000000000 --- a/code/modules/mob/living/silicon/ai/freelook/visibility_interface.dm +++ /dev/null @@ -1,10 +0,0 @@ -/datum/visibility_interface/ai_eye - chunk_type = /datum/visibility_chunk/camera - -/datum/visibility_interface/ai_eye/getClient() - var/mob/aiEye/eye = controller - if (!eye) - return FALSE - if (!eye.ai) - return FALSE - return eye.ai.client diff --git a/code/modules/mob/living/silicon/ai/laws.dm b/code/modules/mob/living/silicon/ai/laws.dm index ab6b19e6190..8e8ceb33c3f 100755 --- a/code/modules/mob/living/silicon/ai/laws.dm +++ b/code/modules/mob/living/silicon/ai/laws.dm @@ -23,6 +23,10 @@ /mob/living/silicon/ai/proc/set_zeroth_law(var/law, var/law_borg) src.laws_sanity_check() src.laws.set_zeroth_law(law, law_borg) + +/mob/living/silicon/ai/proc/clear_zeroth_law(var/law_borg) + src.laws_sanity_check() + src.laws.clear_zeroth_law(law_borg) /mob/living/silicon/ai/proc/add_inherent_law(var/law) src.laws_sanity_check() @@ -108,7 +112,7 @@ number++ -/mob/living/silicon/ai/verb/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite +/mob/living/silicon/ai/proc/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite set category = "AI Commands" set name = "State Laws" diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index a4a0d5bdc28..477565b9cca 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -166,7 +166,9 @@ src << "Receiving control information from APC." sleep(2) //bring up APC dialog + apc_override = 1 theAPC.attack_ai(src) + apc_override = 0 src:aiRestorePowerRoutine = 3 src << "Here are your current laws:" src.show_laws() diff --git a/code/modules/mob/living/silicon/ai/nano.dm b/code/modules/mob/living/silicon/ai/nano.dm new file mode 100644 index 00000000000..f9bb7a25d79 --- /dev/null +++ b/code/modules/mob/living/silicon/ai/nano.dm @@ -0,0 +1,10 @@ +var/obj/nano_module/crew_monitor/crew_monitor + +/mob/living/silicon/ai/proc/init_subsystems() + crew_monitor = new(src) + +/mob/living/silicon/ai/proc/nano_crew_monitor() + set category = "AI Commands" + set name = "Crew Monitor" + + crew_monitor.ui_interact(usr) \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm index e535a2dedee..5a4398485ed 100644 --- a/code/modules/mob/living/silicon/ai/say.dm +++ b/code/modules/mob/living/silicon/ai/say.dm @@ -1,32 +1,8 @@ /mob/living/silicon/ai/say(var/message) - if(parent && istype(parent) && parent.stat != 2) - parent.say(message) - return - //If there is a defined "parent" AI, it is actually an AI, and it is alive, anything the AI tries to say is said by the parent instead. - ..(message) - -/mob/living/silicon/ai/say_understands(var/other) - if (istype(other, /mob/living/carbon/human)) - return 1 - if (istype(other, /mob/living/silicon/robot)) - return 1 - if (istype(other, /mob/living/silicon/decoy)) - return 1 - if (istype(other, /mob/living/carbon/brain)) - return 1 - if (istype(other, /mob/living/silicon/pai)) - return 1 - return ..() - -/mob/living/silicon/ai/say_quote(var/text) - var/ending = copytext(text, length(text)) - - if (ending == "?") - return "queries, \"[text]\""; - else if (ending == "!") - return "declares, \"[text]\""; - - return "states, \"[text]\""; + if(parent && istype(parent) && parent.stat != 2) + return parent.say(message) + //If there is a defined "parent" AI, it is actually an AI, and it is alive, anything the AI tries to say is said by the parent instead. + return ..(message) /mob/living/silicon/ai/proc/IsVocal() @@ -36,44 +12,28 @@ var/const/VOX_DELAY = 100 var/const/VOX_PATH = "sound/vox_fem/" /mob/living/silicon/ai/verb/announcement_help() - - set name = "Announcement Help" - set desc = "Display a list of vocal words to announce to the crew." - set category = "AI Commands" - - - var/dat = "Here is a list of words you can type into the 'Announcement' button to create sentences to vocally announce to everyone on the same level at you.
\ -
  • You can also click on the word to preview it.
  • \ -
  • You can only say 30 words for every announcement.
  • \ -
  • Do not use punctuation as you would normally, if you want a pause you can use the full stop and comma characters by separating them with spaces, like so: 'Alpha . Test , Bravo'.
\ - WARNING:
Misuse of the announcement system will get you job banned.
" - - var/index = 0 - for(var/word in vox_sounds) - index++ - dat += "[capitalize(word)]" - if(index != vox_sounds.len) - dat += " / " - - var/datum/browser/popup = new(src, "announce_help", "Announcement Help", 500, 400) - popup.set_content(dat) - popup.open() - - -/mob/living/silicon/ai/proc/announcement() - - set name = "Announcement" - set desc = "Create a vocal announcement by typing in the available words to create a sentence." + set name = "Announcement Help" + set desc = "Display a list of vocal words to announce to the crew." set category = "AI Commands" - if(src.stat == 2) - src << "You can't call the shuttle because you are dead!" - return - if(istype(usr,/mob/living/silicon/ai)) - var/mob/living/silicon/ai/AI = src - if(AI.control_disabled) - usr << "Wireless control is disabled!" - return + var/dat = "Here is a list of words you can type into the 'Announcement' button to create sentences to vocally announce to everyone on the same level at you.
\ +
  • You can also click on the word to preview it.
  • \ +
  • You can only say 30 words for every announcement.
  • \ +
  • Do not use punctuation as you would normally, if you want a pause you can use the full stop and comma characters by separating them with spaces, like so: 'Alpha . Test , Bravo'.
\ + WARNING:
Misuse of the announcement system will get you job banned.
" + + var/index = 0 + for(var/word in vox_sounds) + index++ + dat += "[capitalize(word)]" + if(index != vox_sounds.len) + dat += " / " + + var/datum/browser/popup = new(src, "announce_help", "Announcement Help", 500, 400) + popup.set_content(dat) + popup.open() + +/mob/living/silicon/ai/proc/ai_announcement() if(announcing_vox > world.time) src << "Please wait [round((announcing_vox - world.time) / 10)] seconds." return @@ -112,27 +72,24 @@ var/const/VOX_PATH = "sound/vox_fem/" /proc/play_vox_word(var/word, var/z_level, var/mob/only_listener) + word = lowertext(word) + if(vox_sounds[word]) + var/sound_file = vox_sounds[word] + var/sound/voice = sound(sound_file, wait = 1, channel = VOX_CHANNEL) + voice.status = SOUND_STREAM - word = lowertext(word) - - if(vox_sounds[word]) - - var/sound_file = vox_sounds[word] - var/sound/voice = sound(sound_file, wait = 1, channel = VOX_CHANNEL) - voice.status = SOUND_STREAM - - // If there is no single listener, broadcast to everyone in the same z level - if(!only_listener) - // Play voice for all mobs in the z level - for(var/mob/M in player_list) - if(M.client) - var/turf/T = get_turf(M) - if(T.z == z_level) - M << voice - else - only_listener << voice - return 1 - return 0 + // If there is no single listener, broadcast to everyone in the same z level + if(!only_listener) + // Play voice for all mobs in the z level + for(var/mob/M in player_list) + if(M.client) + var/turf/T = get_turf(M) + if(T.z == z_level && !isdeaf(M)) + M << voice + else + only_listener << voice + return 1 + return 0 // VOX sounds moved to /code/defines/vox_sounds.dm diff --git a/code/modules/mob/living/silicon/mommi/life.dm b/code/modules/mob/living/silicon/mommi/life.dm index 948d5967888..eb7aa1dd700 100644 --- a/code/modules/mob/living/silicon/mommi/life.dm +++ b/code/modules/mob/living/silicon/mommi/life.dm @@ -133,7 +133,7 @@ / /mob/living/silicon/robot/mommi/handle_regular_hud_updates() - if (src.stat == 2 || M_XRAY in mutations || src.sight_mode & BORGXRAY) + if (src.stat == 2 || XRAY in mutations || src.sight_mode & BORGXRAY) src.sight |= SEE_TURFS src.sight |= SEE_MOBS src.sight |= SEE_OBJS @@ -264,7 +264,7 @@ if (src.client) src.client.screen -= src.contents for(var/obj/I in src.contents) - //if(I && !(istype(I,/obj/item/weapon/cell) || istype(I,/obj/item/device/radio) || istype(I,/obj/machinery/camera) || istype(I,/obj/item/device/mmi))) + //if(I && !(istype(I,/obj/item/weapon/stock_parts/cell) || istype(I,/obj/item/device/radio) || istype(I,/obj/machinery/camera) || istype(I,/obj/item/device/mmi))) if(I) // Make sure we're not showing any of our internal components, as that would be lewd. // This way of doing it ensures that shit we pick up will be visible, wheras shit inside of us isn't. diff --git a/code/modules/mob/living/silicon/mommi/mommi.dm b/code/modules/mob/living/silicon/mommi/mommi.dm index 79034c8782c..b532b2f0da2 100644 --- a/code/modules/mob/living/silicon/mommi/mommi.dm +++ b/code/modules/mob/living/silicon/mommi/mommi.dm @@ -40,7 +40,7 @@ They can only use one tool at a time, they can't choose modules, and they have 1 updateicon() if(!cell) - cell = new /obj/item/weapon/cell(src) + cell = new /obj/item/weapon/stock_parts/cell(src) cell.maxcharge = 7500 cell.charge = 7500 ..() @@ -148,8 +148,8 @@ They can only use one tool at a time, they can't choose modules, and they have 1 real_name = changed_name name = real_name -/mob/living/silicon/robot/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do +/mob/living/silicon/robot/attackby(obj/item/weapon/W as obj, mob/user as mob, params) + if (istype(W, /obj/item/weapon/restraints/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do return if (istype(W, /obj/item/weapon/weldingtool)) @@ -164,8 +164,8 @@ They can only use one tool at a time, they can't choose modules, and they have 1 user << "Need more welding fuel!" return - else if(istype(W, /obj/item/weapon/cable_coil) && wiresexposed) - var/obj/item/weapon/cable_coil/coil = W + else if(istype(W, /obj/item/stack/cable_coil) && wiresexposed) + var/obj/item/stack/cable_coil/coil = W adjustFireLoss(-30) updatehealth() coil.use(1) @@ -190,7 +190,7 @@ They can only use one tool at a time, they can't choose modules, and they have 1 opened = 1 updateicon() - else if (istype(W, /obj/item/weapon/cell) && opened) // trying to put a cell inside + else if (istype(W, /obj/item/weapon/stock_parts/cell) && opened) // trying to put a cell inside if(wiresexposed) user << "Close the panel first." else if(cell) @@ -240,68 +240,6 @@ They can only use one tool at a time, they can't choose modules, and they have 1 else user << "\red Access denied." - else if(istype(W, /obj/item/weapon/card/emag)) // trying to unlock with an emag card - if(!opened)//Cover is closed - if(locked) - if(prob(90)) - user << "You emag the cover lock." - locked = 0 - else - user << "You fail to emag the cover lock." - if(prob(25)) - src << "Hack attempt detected." - else - user << "The cover is already unlocked." - return - - if(opened)//Cover is open - if(emagged) return//Prevents the X has hit Y with Z message also you cant emag them twice - if(wiresexposed) - user << "You must close the panel first" - return - else - sleep(6) - if(prob(50)) - emagged = 1 - lawupdate = 0 - connected_ai = null - user << "You emag [src]'s interface." -// message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.") - log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.") - clear_supplied_laws() - clear_inherent_laws() - laws = new /datum/ai_laws/syndicate_override - var/time = time2text(world.realtime,"hh:mm:ss") - lawchanges.Add("[time] : [user.name]([user.key]) emagged [name]([key])") - set_zeroth_law("Only [user.real_name] and people he designates as being such are Syndicate Agents.") - src << "\red ALERT: Foreign software detected." - sleep(5) - src << "\red Initiating diagnostics..." - sleep(20) - src << "\red SynBorg v1.7 loaded." - sleep(5) - src << "\red LAW SYNCHRONISATION ERROR" - sleep(5) - src << "\red Would you like to send a report to NanoTraSoft? Y/N" - sleep(10) - src << "\red > N" - sleep(20) - src << "\red ERRORERRORERROR" - src << "Obey these laws:" - laws.show_laws(src) - src << "\red \b ALERT: [user.real_name] is your new master. Obey your new laws and his commands." - if(src.module && istype(src.module, /obj/item/weapon/robot_module/miner)) - for(var/obj/item/weapon/pickaxe/borgdrill/D in src.module.modules) - del(D) - src.module.modules += new /obj/item/weapon/pickaxe/diamonddrill(src.module) - src.module.rebuild() - updateicon() - else - user << "You fail to [ locked ? "unlock" : "lock"] [src]'s interface." - if(prob(25)) - src << "Hack attempt detected." - return - else if(istype(W, /obj/item/borg/upgrade/)) var/obj/item/borg/upgrade/U = W if(!opened) @@ -322,6 +260,68 @@ They can only use one tool at a time, they can't choose modules, and they have 1 else spark_system.start() return ..() + +/mob/living/silicon/robot/mommi/emag_act(user as mob) + if(!opened)//Cover is closed + if(locked) + if(prob(90)) + user << "You emag the cover lock." + locked = 0 + else + user << "You fail to emag the cover lock." + if(prob(25)) + src << "Hack attempt detected." + else + user << "The cover is already unlocked." + return + + if(opened)//Cover is open + if(emagged) return//Prevents the X has hit Y with Z message also you cant emag them twice + if(wiresexposed) + user << "You must close the panel first" + return + else + sleep(6) + if(prob(50)) + emagged = 1 + lawupdate = 0 + connected_ai = null + user << "You emag [src]'s interface." +// message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.") + log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.") + clear_supplied_laws() + clear_inherent_laws() + laws = new /datum/ai_laws/syndicate_override + var/time = time2text(world.realtime,"hh:mm:ss") + lawchanges.Add("[time] : [user.name]([user.key]) emagged [name]([key])") + set_zeroth_law("Only [user.real_name] and people he designates as being such are Syndicate Agents.") + src << "\red ALERT: Foreign software detected." + sleep(5) + src << "\red Initiating diagnostics..." + sleep(20) + src << "\red SynBorg v1.7 loaded." + sleep(5) + src << "\red LAW SYNCHRONISATION ERROR" + sleep(5) + src << "\red Would you like to send a report to NanoTraSoft? Y/N" + sleep(10) + src << "\red > N" + sleep(20) + src << "\red ERRORERRORERROR" + src << "Obey these laws:" + laws.show_laws(src) + src << "\red \b ALERT: [user.real_name] is your new master. Obey your new laws and his commands." + if(src.module && istype(src.module, /obj/item/weapon/robot_module/miner)) + for(var/obj/item/weapon/pickaxe/borgdrill/D in src.module.modules) + del(D) + src.module.modules += new /obj/item/weapon/pickaxe/diamonddrill(src.module) + src.module.rebuild() + updateicon() + else + user << "You fail to [ locked ? "unlock" : "lock"] [src]'s interface." + if(prob(25)) + src << "Hack attempt detected." + return /mob/living/silicon/robot/mommi/attack_hand(mob/user) add_fingerprint(user) diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 16ac8d7ec9c..005ad324045 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -71,6 +71,7 @@ var/obj/item/radio/integrated/signal/sradio // AI's signaller + var/translator_on = 0 // keeps track of the translator module /mob/living/silicon/pai/New(var/obj/item/device/paicard) canmove = 0 @@ -81,6 +82,14 @@ if(!card.radio) card.radio = new /obj/item/device/radio(src.card) radio = card.radio + + //Default languages without universal translator software + add_language("Galactic Common", 1) + add_language("Sol Common", 1) + add_language("Tradeband", 1) + add_language("Gutter", 1) + add_language("Trinary", 1) + //Verbs for pAI mobile form, chassis and Say flavor text verbs += /mob/living/silicon/pai/proc/choose_chassis verbs += /mob/living/silicon/pai/proc/choose_verbs @@ -204,6 +213,7 @@ if(M.melee_damage_upper == 0) M.emote("[M.friendly] [src]") else + M.do_attack_animation(src) if(M.attack_sound) playsound(loc, M.attack_sound, 50, 1, 1) for(var/mob/O in viewers(src, null)) @@ -231,6 +241,7 @@ O.show_message(text("\blue [M] caresses [src]'s casing with its scythe like arm."), 1) else //harm + M.do_attack_animation(src) var/damage = rand(10, 20) if (prob(90)) playsound(src.loc, 'sound/weapons/slash.ogg', 25, 1, -1) @@ -334,7 +345,7 @@ //I'm not sure how much of this is necessary, but I would rather avoid issues. if(istype(card.loc,/mob)) var/mob/holder = card.loc - holder.drop_from_inventory(card) + holder.unEquip(card) else if(istype(card.loc,/obj/item/clothing/suit/space/space_ninja)) var/obj/item/clothing/suit/space/space_ninja/holder = card.loc holder.pai = null @@ -415,7 +426,7 @@ canmove = !resting //Overriding this will stop a number of headaches down the track. -/mob/living/silicon/pai/attackby(obj/item/weapon/W as obj, mob/user as mob) +/mob/living/silicon/pai/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(W.force) visible_message("[user.name] attacks [src] with [W]!") src.adjustBruteLoss(W.force) @@ -504,3 +515,6 @@ close_up() return 2 +// No binary for pAIs. +/mob/living/silicon/pai/binarycheck() + return 0 \ No newline at end of file diff --git a/code/modules/mob/living/silicon/pai/recruit.dm b/code/modules/mob/living/silicon/pai/recruit.dm index 9ffc8e0a003..1b4b2fb1d40 100644 --- a/code/modules/mob/living/silicon/pai/recruit.dm +++ b/code/modules/mob/living/silicon/pai/recruit.dm @@ -64,32 +64,32 @@ var/datum/paiController/paiController // Global handler for pAI candidates if("name") t = input("Enter a name for your pAI", "pAI Name", candidate.name) as text if(t) - candidate.name = copytext(sanitize(t),1,MAX_NAME_LEN) + candidate.name = sanitize(copytext(t,1,MAX_NAME_LEN)) if("desc") t = input("Enter a description for your pAI", "pAI Description", candidate.description) as message if(t) - candidate.description = copytext(sanitize(t),1,MAX_MESSAGE_LEN) + candidate.description = sanitize(copytext(t,1,MAX_MESSAGE_LEN)) if("role") t = input("Enter a role for your pAI", "pAI Role", candidate.role) as text if(t) - candidate.role = copytext(sanitize(t),1,MAX_MESSAGE_LEN) + candidate.role = sanitize(copytext(t,1,MAX_MESSAGE_LEN)) if("ooc") t = input("Enter any OOC comments", "pAI OOC Comments", candidate.comments) as message if(t) - candidate.comments = copytext(sanitize(t),1,MAX_MESSAGE_LEN) + candidate.comments = sanitize(copytext(t,1,MAX_MESSAGE_LEN)) if("save") candidate.savefile_save(usr) if("load") candidate.savefile_load(usr) //In case people have saved unsanitized stuff. if(candidate.name) - candidate.name = copytext(sanitize(candidate.name),1,MAX_NAME_LEN) + candidate.name = sanitize(copytext(candidate.name,1,MAX_NAME_LEN)) if(candidate.description) - candidate.description = copytext(sanitize(candidate.description),1,MAX_MESSAGE_LEN) + candidate.description = sanitize(copytext(candidate.description,1,MAX_MESSAGE_LEN)) if(candidate.role) - candidate.role = copytext(sanitize(candidate.role),1,MAX_MESSAGE_LEN) + candidate.role = sanitize(copytext(candidate.role,1,MAX_MESSAGE_LEN)) if(candidate.comments) - candidate.comments = copytext(sanitize(candidate.comments),1,MAX_MESSAGE_LEN) + candidate.comments = sanitize(copytext(candidate.comments,1,MAX_MESSAGE_LEN)) if("submit") if(candidate) diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index 4f7bd1a1c61..a663ae6a738 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -268,7 +268,7 @@ src.medHUD = !src.medHUD if("translator") if(href_list["toggle"]) - src.universal_speak = !src.universal_speak + src.translator_toggle() if("doorjack") if(href_list["jack"]) if(src.cable && src.cable.machine) @@ -327,7 +327,7 @@ if(s == "medical HUD") //This file has to be saved as ANSI or this will not display correctly dat += "Medical Analysis Suite [(src.medHUD) ? "" : ""]
" if(s == "universal translator") //This file has to be saved as ANSI or this will not display correctly - dat += "Universal Translator [(src.universal_speak) ? "" : ""]
" + dat += "Universal Translator [(src.translator_on) ? "" : ""]
" if(s == "projection array") dat += "Projection Array
" if(s == "camera jack") @@ -687,4 +687,38 @@ else dat += addtext("
") dat += "

Name

Status

Location

Control

[Bot.hacked ? "(!) [Bot.name]" : Bot.name] ([Bot.bot_type_name])
From", index["owner"],": ", index["message"], "
" - return dat \ No newline at end of file + return dat + +/mob/living/silicon/pai/proc/translator_toggle() + + // Sol Common, Tradeband, Gutter and Trinary are added with New() and are therefore the current default, always active languages + + if(translator_on) + translator_on = 0 + + remove_language("Sinta'unathi") + remove_language("Siik'tajr") + remove_language("Skrellian") + remove_language("Vox-pidgin") + remove_language("Rootspeak") + remove_language("Trinary") + remove_language("Chittin") + remove_language("Bubblish") + remove_language("Clownish") + + src << "\blue Translator Module toggled OFF." + + else + translator_on = 1 + + add_language("Sinta'unathi") + add_language("Siik'tajr") + add_language("Skrellian") + add_language("Vox-pidgin") + add_language("Rootspeak") + add_language("Trinary") + add_language("Chittin") + add_language("Bubblish") + add_language("Clownish") + + src << "\blue Translator Module toggled ON." \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm index 7d867036d5a..73ec259f7f7 100644 --- a/code/modules/mob/living/silicon/robot/component.dm +++ b/code/modules/mob/living/silicon/robot/component.dm @@ -121,6 +121,11 @@ /mob/living/silicon/robot/proc/is_component_functioning(module_name) var/datum/robot_component/C = components[module_name] return C && C.installed == 1 && C.toggled && C.is_powered() + +// Returns component by it's string name +/mob/living/silicon/robot/proc/get_component(var/component_name) + var/datum/robot_component/C = components[component_name] + return C /obj/item/broken_device name = "broken component" @@ -168,7 +173,7 @@ icon_state = "robotanalyzer" item_state = "analyzer" desc = "A hand-held scanner able to diagnose robotic injuries." - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT throwforce = 3 w_class = 2.0 @@ -178,7 +183,7 @@ var/mode = 1; /obj/item/device/robotanalyzer/attack(mob/living/M as mob, mob/living/user as mob) - if(( (M_CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50)) + if(( (CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50)) user << text("\red You try to analyze the floor's vitals!") for(var/mob/O in viewers(M, null)) O.show_message(text("\red [user] has analyzed the floor's vitals!"), 1) diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index 0073729778d..12c5548f51c 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -13,6 +13,7 @@ lawupdate = 0 density = 1 req_access = list(access_engine, access_robotics) + local_transmit = 1 // We need to keep track of a few module items so we don't need to do list operations // every time we need them. These get set in New() after the module is chosen. @@ -24,13 +25,16 @@ //Used for self-mailing. var/mail_destination = 0 +// var/sprite[0] - //Used for pulling. /mob/living/silicon/robot/drone/New() ..() + remove_language("Robot Talk") + add_language("Drone Talk", 1) + if(camera && "Robots" in camera.network) camera.network.Add("Engineering") @@ -85,84 +89,12 @@ /mob/living/silicon/robot/drone/choose_icon() return + /mob/living/silicon/robot/drone/pick_module() return -//Drones can only use binary and say emotes. NOTHING else. -//TBD, fix up boilerplate. ~ Z -/mob/living/silicon/robot/drone/say(var/message) - if (!message) - return - - if (src.client) - if(client.prefs.muted & MUTE_IC) - src << "You cannot send IC messages (muted)." - return - if (src.client.handle_spam_prevention(message,MUTE_IC)) - return - - if (stat == 2) - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) - return say_dead(message) - - //Must be concious to speak - if (stat) - return - - if(copytext(message,1,2) == "*") - return emote(copytext(message,2)) - - if (length(message) >= 2) - var/prefix = copytext(message, 1, 3) - if (department_radio_keys[prefix] == "drone") - message = copytext(message, 3) - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) - - if(istype(src, /mob/living/silicon/robot/drone)) - var/mob/living/silicon/robot/drone/R = src - if(!R.is_component_functioning("comms")) - src << "\red Your drone communications component isn't functional." - return - drone_talk(message) - else - var/list/listeners = hearers(5,src) - listeners |= src - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) - for(var/mob/living/silicon/D in listeners) - if(D.client) - D << "[src] transmits, \"[message]\"" - - for (var/mob/M in player_list) - if (!M.client) - continue - if (istype(M, /mob/new_player)) - continue - else if(M.stat == 2 && (M.client.prefs.toggles & CHAT_GHOSTEARS) && src.client) - M << "[src] (Follow) transmits, \"[message]\"" - else if(M.stat == 2 && src.client && M in listeners) - M << "[src] (Follow) transmits, \"[message]\"" - -/mob/living/proc/drone_talk(var/message) - log_say("[key_name(src)] : [message]") - message = trim(message) - - if (!message) - return - - var/message_a = say_quote(message) - var/rendered = "Drone Talk, [name] [message_a]" - - for (var/mob/living/S in living_mob_list) - if(istype(S, /mob/living/silicon/robot/drone)) - S.show_message(rendered, 2) - - for (var/mob/S in dead_mob_list) - if(!istype(S,/mob/new_player) && !istype(S,/mob/living/carbon/brain)) - var/rendered2 = "Drone Talk, [name] (Follow) [message_a]" - S.show_message(rendered2, 2) - //Drones cannot be upgraded with borg modules so we need to catch some items before they get used in ..(). -/mob/living/silicon/robot/drone/attackby(obj/item/weapon/W as obj, mob/user as mob) +/mob/living/silicon/robot/drone/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/borg/upgrade/)) user << "\red The maintenance drone chassis not compatible with \the [W]." @@ -172,41 +104,6 @@ user << "The machine is hermetically sealed. You can't open the case." return - else if (istype(W, /obj/item/weapon/card/emag)) - - if(!client || stat == 2) - user << "\red There's not much point subverting this heap of junk." - return - - if(emagged) - src << "\red [user] attempts to load subversive software into you, but your hacked subroutined ignore the attempt." - user << "\red You attempt to subvert [src], but the sequencer has no effect." - return - - user << "\red You swipe the sequencer across [src]'s interface and watch its eyes flicker." - src << "\red You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script." - - var/obj/item/weapon/card/emag/emag = W - emag.uses-- - - message_admins("[key_name_admin(user)] emagged drone [key_name_admin(src)]. Laws overridden.") - log_game("[key_name(user)] emagged drone [key_name(src)]. Laws overridden.") - var/time = time2text(world.realtime,"hh:mm:ss") - lawchanges.Add("[time] : [user.name]([user.key]) emagged [name]([key])") - - emagged = 1 - lawupdate = 0 - connected_ai = null - clear_supplied_laws() - clear_inherent_laws() - laws = new /datum/ai_laws/syndicate_override - set_zeroth_law("Only [user.real_name] and people he designates as being such are Syndicate Agents.") - - src << "Obey these laws:" - laws.show_laws(src) - src << "\red \b ALERT: [user.real_name] is your new master. Obey your new laws and his commands." - return - else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) if(stat == 2) @@ -243,6 +140,41 @@ ..() +/mob/living/silicon/robot/drone/emag_act(user as mob) + if(!client || stat == 2) + user << "\red There's not much point subverting this heap of junk." + return + + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user + + if(emagged) + src << "\red [user] attempts to load subversive software into you, but your hacked subroutined ignore the attempt." + user << "\red You attempt to subvert [src], but the sequencer has no effect." + return + + user << "\red You swipe the sequencer across [src]'s interface and watch its eyes flicker." + src << "\red You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script." + + message_admins("[key_name_admin(user)] emagged drone [key_name_admin(src)]. Laws overridden.") + log_game("[key_name(user)] emagged drone [key_name(src)]. Laws overridden.") + var/time = time2text(world.realtime,"hh:mm:ss") + lawchanges.Add("[time] : [H.name]([H.key]) emagged [name]([key])") + + emagged = 1 + lawupdate = 0 + connected_ai = null + clear_supplied_laws() + clear_inherent_laws() + laws = new /datum/ai_laws/syndicate_override + set_zeroth_law("Only [H.real_name] and people he designates as being such are Syndicate Agents.") + + src << "Obey these laws:" + laws.show_laws(src) + src << "\red \b ALERT: [H.real_name] is your new master. Obey your new laws and his commands." + return + //DRONE LIFE/DEATH //For some goddamn reason robots have this hardcoded. Redefining it for our fragile friends here. @@ -343,6 +275,19 @@ src << "Don't invade their worksites, don't steal their resources, don't tell them about the changeling in the toilets." src << "If a crewmember has noticed you, you are probably breaking your first law." +/* + sprite["Default"] = "repairbot" + sprite["Mk2 Mousedrone"] = "mk2" + sprite["Mk3 Monkeydrone"] = "mk3" + var/icontype + icontype = input(player,"Pick an icon") in sprite + icon_state = sprite[icontype] + updateicon() + + choose_icon(6,sprite) +*/ + + /mob/living/silicon/robot/drone/Bump(atom/movable/AM as mob|obj, yes) if (!yes || ( \ !istype(AM,/obj/machinery/door) && \ diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm index 1db5b3e059f..b9c9acc52f6 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm @@ -8,7 +8,7 @@ //Has a list of items that it can hold. var/list/can_hold = list( - /obj/item/weapon/cell, + /obj/item/weapon/stock_parts/cell, /obj/item/weapon/firealarm_electronics, /obj/item/weapon/airalarm_electronics, /obj/item/weapon/airlock_electronics, @@ -86,7 +86,7 @@ wrapped.loc = user //Pass the attack on to the target. This might delete/relocate wrapped. - target.attackby(wrapped,user) + target.attackby(wrapped,user, params) //If wrapped did neither get deleted nor put into target, put it back into the gripper. if(wrapped && user && (wrapped.loc == user)) diff --git a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm index d886cb0b5a2..0220dcc4d17 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm @@ -97,6 +97,12 @@ if(jobban_isbanned(src,"nonhumandept") || jobban_isbanned(src,"Drone")) usr << "\red You are banned from playing drones and cannot spawn as a drone." return + + var/drone_age = 14 // 14 days to play as a drone + var/player_age_check = check_client_age(usr.client, drone_age) + if(player_age_check && config.use_age_restriction_for_antags) + usr << "This role is not yet available to you. You need to wait another [player_age_check] days." + return var/deathtime = world.time - src.timeofdeath var/joinedasobserver = 0 diff --git a/code/modules/mob/living/silicon/robot/emote.dm b/code/modules/mob/living/silicon/robot/emote.dm index 6bf18971ba6..8efab8a0f57 100644 --- a/code/modules/mob/living/silicon/robot/emote.dm +++ b/code/modules/mob/living/silicon/robot/emote.dm @@ -8,6 +8,21 @@ if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_' act = copytext(act,1,length(act)) + //Emote Cooldown System (it's so simple!) + // proc/handle_emote_CD() located in [code\modules\mob\emote.dm] + var/on_CD = 0 + switch(act) + //Cooldown-inducing emotes + if("ping","buzz","beep","law") //halt is exempt because it's used to stop criminal scum + on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm + //Everything else, including typos of the above emotes + else + on_CD = 0 //If it doesn't induce the cooldown, we won't check for the cooldown + + if(on_CD == 1) // Check if we need to suppress the emote attempt. + return // Suppress emote, you're still cooling off. + //--FalseIncarnate + switch(act) if ("me") if (src.client) diff --git a/code/modules/mob/living/silicon/robot/laws.dm b/code/modules/mob/living/silicon/robot/laws.dm index 84377b6adb4..e0d7859a398 100644 --- a/code/modules/mob/living/silicon/robot/laws.dm +++ b/code/modules/mob/living/silicon/robot/laws.dm @@ -77,6 +77,10 @@ laws_sanity_check() laws.set_zeroth_law(law) +/mob/living/silicon/robot/proc/clear_zeroth_law() + laws_sanity_check() + laws.clear_zeroth_law() + /mob/living/silicon/robot/proc/add_inherent_law(var/law) laws_sanity_check() laws.add_inherent_law(law) @@ -152,7 +156,7 @@ number++ -/mob/living/silicon/robot/verb/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite +/mob/living/silicon/robot/proc/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite set category = "Robot Commands" set name = "State Laws" var/list = "Which laws do you want to include when stating them for the crew?

" diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index 3bea2e0ee96..8171b891977 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -154,7 +154,7 @@ /mob/living/silicon/robot/proc/handle_regular_hud_updates() - if (src.stat == 2 || M_XRAY in mutations || src.sight_mode & BORGXRAY) + if (src.stat == 2 || XRAY in mutations || src.sight_mode & BORGXRAY) src.sight |= SEE_TURFS src.sight |= SEE_MOBS src.sight |= SEE_OBJS @@ -309,7 +309,7 @@ if (src.client) src.client.screen -= src.contents for(var/obj/I in src.contents) - if(I && !(istype(I,/obj/item/weapon/cell) || istype(I,/obj/item/device/radio) || istype(I,/obj/machinery/camera) || istype(I,/obj/item/device/mmi))) + if(I && !(istype(I,/obj/item/weapon/stock_parts/cell) || istype(I,/obj/item/device/radio) || istype(I,/obj/machinery/camera) || istype(I,/obj/item/device/mmi))) src.client.screen += I if(src.module_state_1) src.module_state_1:screen_loc = ui_inv1 diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 1b12f3595fd..9bb0eee9203 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1,3 +1,8 @@ +var/list/robot_verbs_default = list( + /mob/living/silicon/robot/proc/sensor_mode, + /mob/living/silicon/robot/proc/checklaws +) + /mob/living/silicon/robot name = "Cyborg" real_name = "Cyborg" @@ -30,7 +35,7 @@ var/obj/item/device/radio/borg/radio = null var/mob/living/silicon/ai/connected_ai = null - var/obj/item/weapon/cell/cell = null + var/obj/item/weapon/stock_parts/cell/cell = null var/obj/machinery/camera/camera = null // Components are basically robot organs. @@ -71,8 +76,7 @@ var/braintype = "Cyborg" var/base_icon = "" var/crisis = 0 - var/hiddenborg = 0 - + var/obj/item/borg/sight/hud/sec/sechud = null var/obj/item/borg/sight/hud/med/healthhud = null @@ -80,34 +84,23 @@ spark_system = new /datum/effect/effect/system/spark_spread() spark_system.set_up(5, 0, src) spark_system.attach(src) + + add_language("Robot Talk", 1) + + wires = new(src) robot_modules_background = new() robot_modules_background.icon_state = "block" robot_modules_background.layer = 19 //Objects that appear on screen are on layer 20, UI should be just below it. - - wires = new(src) - ident = rand(1, 999) updatename("Default") updateicon() - if(mmi == null) - mmi = new /obj/item/device/mmi/posibrain(src) //Give the borg an MMI if he spawns without for some reason. (probably not the correct way to spawn a posibrain, but it works) - mmi.icon_state="posibrain-occupied" - if(syndie) - if(!cell) - cell = new /obj/item/weapon/cell(src) - laws = new /datum/ai_laws/antimov() - lawupdate = 0 - scrambledcodes = 1 - cell.maxcharge = 25000 - cell.charge = 25000 - module = new /obj/item/weapon/robot_module/syndicate(src) - hands.icon_state = "standard" - icon_state = "secborg" - modtype = "Security" - init(alien) radio = new /obj/item/device/radio/borg(src) + common_radio = radio + + init() + if(!scrambledcodes && !camera) camera = new /obj/machinery/camera(src) camera.c_tag = real_name @@ -115,6 +108,10 @@ if(wires.IsCameraCut()) // 5 = BORG CAMERA camera.status = 0 + if(mmi == null) + mmi = new /obj/item/device/mmi/posibrain(src) //Give the borg an MMI if he spawns without for some reason. (probably not the correct way to spawn a posibrain, but it works) + mmi.icon_state="posibrain-occupied" + initialize_components() //if(!unfinished) // Create all the robot parts. @@ -124,11 +121,13 @@ C.wrapped = new C.external_type if(!cell) - cell = new /obj/item/weapon/cell(src) + cell = new /obj/item/weapon/stock_parts/cell(src) cell.maxcharge = 7500 cell.charge = 7500 ..() + + add_robot_verbs() if(cell) var/datum/robot_component/cell_component = components["power cell"] @@ -146,17 +145,9 @@ hud_list[NATIONS_HUD] = image('icons/mob/hud.dmi', src, "hudblank") /mob/living/silicon/robot/proc/init(var/alien=0) - if(hiddenborg) - playsound(loc, 'sound/voice/liveagain.ogg', 75, 1) - return aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src) - if(mmi.alien || alien) - laws = new /datum/ai_laws/alienmov() - connected_ai = select_active_alien_ai() - scrambledcodes = 1 - else - make_laws() - connected_ai = select_active_ai_with_fewest_borgs() + make_laws() + connected_ai = select_active_ai_with_fewest_borgs() if(connected_ai) connected_ai.connected_robots += src lawsync() @@ -172,8 +163,15 @@ if (!rbPDA) rbPDA = new/obj/item/device/pda/ai(src) rbPDA.set_name_and_job(custom_name,braintype) - if(hiddenborg) + if(scrambledcodes) rbPDA.hidden = 1 + +/mob/living/silicon/robot/binarycheck() + if(is_component_functioning("comms")) + var/datum/robot_component/RC = get_component("comms") + use_power(RC.energy_consumption) + return 1 + return 0 //If there's an MMI in the robot, have it ejected when the mob goes away. --NEO //Improved /N @@ -188,16 +186,15 @@ /mob/living/silicon/robot/proc/pick_module() if(module) return - var/list/modules = list("Standard", "Engineering", "Surgeon", "Crisis", "Miner", "Janitor", "Service", "Security") + var/list/modules = list("Standard", "Engineering", "Medical", "Miner", "Janitor", "Service", "Security") if(security_level == (SEC_LEVEL_GAMMA || SEC_LEVEL_EPSILON) || crisis) src << "\red Crisis mode active. Combat module available." modules+="Combat" if(mmi != null && mmi.alien) - modules="Hunter" + modules = "Hunter" modtype = input("Please, select a module!", "Robot", null, null) in modules designation = modtype var/module_sprites[0] //Used to store the associations between sprite names and sprite index. - var/channels = list() if(module) return @@ -205,14 +202,14 @@ switch(modtype) if("Standard") module = new /obj/item/weapon/robot_module/standard(src) - channels = list("Service" = 1) + module.channels = list("Service" = 1) module_sprites["Basic"] = "robot_old" module_sprites["Android"] = "droid" module_sprites["Default"] = "robot" if("Service") module = new /obj/item/weapon/robot_module/butler(src) - channels = list("Service" = 1) + module.channels = list("Service" = 1) module_sprites["Waitress"] = "Service" module_sprites["Kent"] = "toiletbot" module_sprites["Bro"] = "Brobot" @@ -221,7 +218,7 @@ /* if("Clerical") module = new /obj/item/weapon/robot_module/clerical(src) - channels = list("Service" = 1) + module.channels = list("Service" = 1) module_sprites["Waitress"] = "Service" module_sprites["Kent"] = "toiletbot" module_sprites["Bro"] = "Brobot" @@ -230,16 +227,16 @@ */ if("Miner") module = new /obj/item/weapon/robot_module/miner(src) - channels = list("Supply" = 1) + module.channels = list("Supply" = 1) if(camera && "Robots" in camera.network) camera.network.Add("MINE") module_sprites["Basic"] = "Miner_old" module_sprites["Advanced Droid"] = "droid-miner" module_sprites["Treadhead"] = "Miner" - if("Crisis") - module = new /obj/item/weapon/robot_module/crisis(src) - channels = list("Medical" = 1) + if("Medical") + module = new /obj/item/weapon/robot_module/medical(src) + module.channels = list("Medical" = 1) if(camera && "Robots" in camera.network) camera.network.Add("Medical") module_sprites["Basic"] = "Medbot" @@ -247,20 +244,9 @@ module_sprites["Advanced Droid"] = "droid-medical" module_sprites["Needles"] = "medicalrobot" - if("Surgeon") - module = new /obj/item/weapon/robot_module/surgeon(src) - channels = list("Medical" = 1) - if(camera && "Robots" in camera.network) - camera.network.Add("Medical") - - module_sprites["Basic"] = "Medbot" - module_sprites["Standard"] = "surgeon" - module_sprites["Advanced Droid"] = "droid-medical" - module_sprites["Needles"] = "medicalrobot" - if("Security") module = new /obj/item/weapon/robot_module/security(src) - channels = list("Security" = 1) + module.channels = list("Security" = 1) module_sprites["Basic"] = "secborg" module_sprites["Red Knight"] = "Security" module_sprites["Black Knight"] = "securityrobot" @@ -268,7 +254,7 @@ if("Engineering") module = new /obj/item/weapon/robot_module/engineering(src) - channels = list("Engineering" = 1) + module.channels = list("Engineering" = 1) if(camera && "Robots" in camera.network) camera.network.Add("Engineering") module_sprites["Basic"] = "Engineering" @@ -277,14 +263,15 @@ if("Janitor") module = new /obj/item/weapon/robot_module/janitor(src) + module.channels = list("Service" = 1) module_sprites["Basic"] = "JanBot2" module_sprites["Mopbot"] = "janitorrobot" module_sprites["Mop Gear Rex"] = "mopgearrex" if("Combat") module = new /obj/item/weapon/robot_module/combat(src) + module.channels = list("Security" = 1) module_sprites["Combat Android"] = "droidcombat" - channels = list("Security" = 1) if("Hunter") updatename(module) @@ -294,7 +281,9 @@ icon_state = "xenoborg-state-a" modtype = "Xeno-Hu" feedback_inc("xeborg_hunter",1) - + + //languages + module.add_languages(src) //Custom_sprite check and entry if (custom_sprite == 1) @@ -308,7 +297,7 @@ status_flags &= ~CANPUSH choose_icon(6,module_sprites) - radio.config(channels) + radio.config(module.channels) notify_ai(2) /mob/living/silicon/robot/proc/updatename(var/prefix as text) @@ -361,7 +350,7 @@ spawn(0) var/newname - newname = copytext(sanitize(input(src,"You are a robot. Enter a name, or leave blank for the default name.", "Name change","") as text),1,MAX_NAME_LEN) + newname = sanitize(copytext(input(src,"You are a robot. Enter a name, or leave blank for the default name.", "Name change","") as text,1,MAX_NAME_LEN)) if (newname != "") notify_ai(3, name, newname) custom_name = newname @@ -451,11 +440,17 @@ C.toggled = 1 src << "\red You enable [C.name]." -/mob/living/silicon/robot/verb/control_hud() +/mob/living/silicon/robot/proc/sensor_mode() set name = "Set Sensor Augmentation" set desc = "Augment visual feed with internal sensor overlays." set category = "Robot Commands" toggle_sensor_mode() + +/mob/living/silicon/robot/proc/add_robot_verbs() + src.verbs |= robot_verbs_default + +/mob/living/silicon/robot/proc/remove_robot_verbs() + src.verbs -= robot_verbs_default /mob/living/silicon/robot/blob_act() if (stat != 2) @@ -566,7 +561,7 @@ now_pushing = 1 if(ismob(AM)) var/mob/tmob = AM - if(istype(tmob, /mob/living/carbon/human) && (M_FAT in tmob.mutations)) + if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) if(prob(20)) usr << "\red You fail to push [tmob]'s fat ass out of the way." now_pushing = 0 @@ -642,8 +637,8 @@ return !cleared -/mob/living/silicon/robot/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do +/mob/living/silicon/robot/attackby(obj/item/weapon/W as obj, mob/user as mob, params) + if (istype(W, /obj/item/weapon/restraints/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do return if(opened) // Are they trying to insert something? @@ -671,6 +666,7 @@ user << "Nothing to fix here!" return var/obj/item/weapon/weldingtool/WT = W + user.changeNext_move(CLICK_CD_MELEE) if (WT.remove_fuel(0)) adjustBruteLoss(-30) updatehealth() @@ -752,7 +748,7 @@ opened = 1 updateicon() - else if (istype(W, /obj/item/weapon/cell) && opened) // trying to put a cell inside + else if (istype(W, /obj/item/weapon/stock_parts/cell) && opened) // trying to put a cell inside var/datum/robot_component/C = components["power cell"] if(wiresexposed) user << "Close the panel first." @@ -808,72 +804,6 @@ else user << "\red Access denied." - else if(istype(W, /obj/item/weapon/card/emag)) // trying to unlock with an emag card - if(!opened)//Cover is closed - if(locked) - if(prob(90)) - var/obj/item/weapon/card/emag/emag = W - emag.uses-- - user << "You emag the cover lock." - locked = 0 - else - user << "You fail to emag the cover lock." - if(prob(25)) - src << "Hack attempt detected." - else - user << "The cover is already unlocked." - return - - if(opened)//Cover is open - if(emagged) return//Prevents the X has hit Y with Z message also you cant emag them twice - if(wiresexposed) - user << "You must close the panel first" - return - else - sleep(6) - if(prob(50)) - emagged = 1 - if(user.hud_used) - user.hud_used.update_robot_modules_display() //Shows/hides the emag item if the inventory screen is already open. - lawupdate = 0 - connected_ai = null - user << "You emag [src]'s interface." -// message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.") - log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.") - clear_supplied_laws() - clear_inherent_laws() - laws = new /datum/ai_laws/syndicate_override - var/time = time2text(world.realtime,"hh:mm:ss") - lawchanges.Add("[time] : [user.name]([user.key]) emagged [name]([key])") - set_zeroth_law("Only [user.real_name] and people he designates as being such are Syndicate Agents.") - src << "\red ALERT: Foreign software detected." - sleep(5) - src << "\red Initiating diagnostics..." - sleep(20) - src << "\red SynBorg v1.7 loaded." - sleep(5) - src << "\red LAW SYNCHRONISATION ERROR" - sleep(5) - src << "\red Would you like to send a report to NanoTraSoft? Y/N" - sleep(10) - src << "\red > N" - sleep(20) - src << "\red ERRORERRORERROR" - src << "Obey these laws:" - laws.show_laws(src) - src << "\red \b ALERT: [user.real_name] is your new master. Obey your new laws and his commands." - if(src.module && istype(src.module, /obj/item/weapon/robot_module/miner)) - for(var/obj/item/weapon/pickaxe/borgdrill/D in src.module.modules) - del(D) - src.module.modules += new /obj/item/weapon/pickaxe/diamonddrill(src.module) - src.module.rebuild() - updateicon() - else - user << "You fail to [ locked ? "unlock" : "lock"] [src]'s interface." - if(prob(25)) - src << "Hack attempt detected." - return - else if(istype(W, /obj/item/borg/upgrade/)) var/obj/item/borg/upgrade/U = W if(!opened) @@ -894,6 +824,73 @@ else spark_system.start() return ..() + +/mob/living/silicon/robot/emag_act(user as mob) + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user + if(!opened)//Cover is closed + if(locked) + if(prob(90)) + user << "You emag the cover lock." + locked = 0 + else + user << "You fail to emag the cover lock." + if(prob(25)) + src << "Hack attempt detected." + else + user << "The cover is already unlocked." + return + + if(opened)//Cover is open + if(emagged) return//Prevents the X has hit Y with Z message also you cant emag them twice + if(wiresexposed) + user << "You must close the panel first" + return + else + sleep(6) + if(prob(50)) + emagged = 1 + if(H.hud_used) + H.hud_used.update_robot_modules_display() //Shows/hides the emag item if the inventory screen is already open. + lawupdate = 0 + connected_ai = null + user << "You emag [src]'s interface." +// message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.") + log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.") + clear_supplied_laws() + clear_inherent_laws() + laws = new /datum/ai_laws/syndicate_override + var/time = time2text(world.realtime,"hh:mm:ss") + lawchanges.Add("[time] : [H.name]([H.key]) emagged [name]([key])") + set_zeroth_law("Only [H.real_name] and people he designates as being such are Syndicate Agents.") + src << "\red ALERT: Foreign software detected." + sleep(5) + src << "\red Initiating diagnostics..." + sleep(20) + src << "\red SynBorg v1.7 loaded." + sleep(5) + src << "\red LAW SYNCHRONISATION ERROR" + sleep(5) + src << "\red Would you like to send a report to NanoTraSoft? Y/N" + sleep(10) + src << "\red > N" + sleep(20) + src << "\red ERRORERRORERROR" + src << "Obey these laws:" + laws.show_laws(src) + src << "\red \b ALERT: [H.real_name] is your new master. Obey your new laws and his commands." + if(src.module && istype(src.module, /obj/item/weapon/robot_module/miner)) + for(var/obj/item/weapon/pickaxe/borgdrill/D in src.module.modules) + del(D) + src.module.modules += new /obj/item/weapon/pickaxe/diamonddrill(src.module) + src.module.rebuild() + updateicon() + else + user << "You fail to [ locked ? "unlock" : "lock"] [src]'s interface." + if(prob(25)) + src << "Hack attempt detected." + return /mob/living/silicon/robot/verb/unlock_own_cover() set category = "Robot Commands" @@ -920,23 +917,21 @@ if ("help") for(var/mob/O in viewers(src, null)) if ((O.client && !( O.blinded ))) - O.show_message(text("\blue [M] caresses [src]'s plating with its scythe like arm."), 1) + O.show_message(text("[M] caresses [src]'s plating with its scythe like arm."), 1) if ("grab") - if (M == src) + if (M == src || anchored) return - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src ) + var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src ) M.put_in_active_hand(G) - grabbed_by += G G.synch() playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has grabbed [] passively!", M, src), 1) + visible_message("[M] has grabbed [src] passively!") if ("harm") + M.do_attack_animation(src) var/damage = rand(10, 20) if (prob(90)) /* @@ -948,33 +943,31 @@ What is this?*/ playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1) - for(var/mob/O in viewers(src, null)) - O.show_message(text("\red [] has slashed at []!", M, src), 1) + visible_message("[M] has slashed at [src]!",\ + "[M] has slashed at [src]!") if(prob(8)) flick("noise", flash) adjustBruteLoss(damage) updatehealth() else playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] took a swipe at []!", M, src), 1) + visible_message("[M] took a swipe at [src]!", \ + "[M] took a swipe at [src]!") if ("disarm") if(!(lying)) + M.do_attack_animation(src) if (rand(1,100) <= 85) Stun(7) step(src,get_dir(M,src)) spawn(5) step(src,get_dir(M,src)) playsound(loc, 'sound/weapons/pierce.ogg', 50, 1, -1) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has forced back []!", M, src), 1) + visible_message("[M] has forced back [src]!",\ + "[M] has forced back [src]!") else playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] attempted to force back []!", M, src), 1) + visible_message("[M] attempted to force back [src]!",\ + "[M] attempted to force back [src]!") return @@ -987,10 +980,9 @@ if(M.Victim) return // can't attack while eating! if (health > -100) - - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red The [M.name] glomps []!", src), 1) + M.do_attack_animation(src) + visible_message("The [M.name] glomps [src]!",\ + "The [M.name] glomps [src]!") var/damage = rand(1, 3) @@ -1021,7 +1013,7 @@ for(var/mob/O in viewers(src, null)) if ((O.client && !( O.blinded ))) - O.show_message(text("\red The [M.name] has electrified []!", src), 1) + O.show_message(text("The [M.name] has electrified []!", src), 1) flick("noise", flash) @@ -1041,12 +1033,11 @@ if(M.melee_damage_upper == 0) M.emote("[M.friendly] [src]") else + M.do_attack_animation(src) if(M.attack_sound) playsound(loc, M.attack_sound, 50, 1, 1) - for(var/mob/O in viewers(src, null)) - O.show_message("\red [M] [M.attacktext] [src]!", 1) - M.attack_log += text("\[[time_stamp()]\] attacked [src.name] ([src.ckey])") - src.attack_log += text("\[[time_stamp()]\] was attacked by [M.name] ([M.ckey])") + visible_message("[M] [M.attacktext] [src]!") + add_logs(M, src, "attacked", admin=0) var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) adjustBruteLoss(damage) updatehealth() @@ -1057,21 +1048,22 @@ add_fingerprint(user) if(opened && !wiresexposed && (!istype(user, /mob/living/silicon))) - var/datum/robot_component/cell_component = components["power cell"] if(cell) cell.updateicon() cell.add_fingerprint(user) user.put_in_active_hand(cell) user << "You remove \the [cell]." cell = null - cell_component.wrapped = null - cell_component.installed = 0 updateicon() - else if(cell_component.installed == -1) - cell_component.installed = 0 - var/obj/item/broken_device = cell_component.wrapped - user << "You remove \the [broken_device]." - user.put_in_active_hand(broken_device) + + if(!opened && (!istype(user, /mob/living/silicon))) + if (user.a_intent == "help") + user.visible_message("[user] pets [src]!", \ + "You pet [src]!") + +/mob/living/silicon/robot/attack_paw(mob/user) + + return attack_hand(user) /mob/living/silicon/robot/proc/allowed(mob/M) //check if it doesn't require any access at all @@ -1398,21 +1390,29 @@ icon_state = "nano_bloodhound" lawupdate = 0 scrambledcodes = 1 - hiddenborg = 1 modtype = "Commando" faction = list("nanotrasen") designation = "NT Combat Cyborg" req_access = list(access_cent_specops) - + /mob/living/silicon/robot/deathsquad/New(loc) - ..() - cell.maxcharge = 50000 - cell.charge = 50000 - radio = new /obj/item/device/radio/borg/deathsquad(src) - module = new /obj/item/weapon/robot_module/deathsquad(src) - laws = new /datum/ai_laws/deathsquad() + if(!cell) + cell = new /obj/item/weapon/stock_parts/cell(src) + cell.maxcharge = 25000 + cell.charge = 25000 - Namepick() + ..() + +/mob/living/silicon/robot/deathsquad/init() + aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src) + + laws = new /datum/ai_laws/deathsquad + module = new /obj/item/weapon/robot_module/deathsquad(src) + + radio = new /obj/item/device/radio/borg/deathsquad(src) + radio.recalculateChannels() + + playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0) /mob/living/silicon/robot/deathsquad/attack_hand(mob/user) if((ckey == null) && searching_for_ckey == 0) @@ -1456,12 +1456,10 @@ get_borg_occupant(user, possiblecandidates) return - /mob/living/silicon/robot/syndicate icon_state = "syndie_bloodhound" lawupdate = 0 scrambledcodes = 1 - hiddenborg = 1 modtype = "Synd" faction = list("syndicate") designation = "Syndicate" @@ -1469,14 +1467,23 @@ req_access = list(access_syndicate) /mob/living/silicon/robot/syndicate/New(loc) - ..() - cell.maxcharge = 25000 - cell.charge = 25000 - radio = new /obj/item/device/radio/borg/syndicate(src) - module = new /obj/item/weapon/robot_module/syndicate(src) - laws = new /datum/ai_laws/syndicate_override() + if(!cell) + cell = new /obj/item/weapon/stock_parts/cell(src) + cell.maxcharge = 25000 + cell.charge = 25000 - Namepick() + ..() + +/mob/living/silicon/robot/syndicate/init() + aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src) + + laws = new /datum/ai_laws/syndicate_override + module = new /obj/item/weapon/robot_module/syndicate(src) + + radio = new /obj/item/device/radio/borg/syndicate(src) + radio.recalculateChannels() + + playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0) /mob/living/silicon/robot/proc/notify_ai(var/notifytype, var/oldname, var/newname) if(!connected_ai) diff --git a/code/modules/mob/living/silicon/robot/robot_items.dm b/code/modules/mob/living/silicon/robot/robot_items.dm index 931cb0556be..dbfcf15caa8 100644 --- a/code/modules/mob/living/silicon/robot/robot_items.dm +++ b/code/modules/mob/living/silicon/robot/robot_items.dm @@ -1,92 +1,4 @@ -// A special tray for the service droid. Allow droid to pick up and drop items as if they were using the tray normally -// Click on table to unload, click on item to load. Otherwise works identically to a tray. -// Unlike the base item "tray", robotrays ONLY pick up food, drinks and condiments. - -/obj/item/weapon/tray/robotray - name = "RoboTray" - desc = "An autoloading tray specialized for carrying refreshments." - -/obj/item/weapon/tray/robotray/afterattack(atom/target, mob/user as mob) - if ( !target ) - return - // pick up items, mostly copied from base tray pickup proc - // see code\game\objects\items\weapons\kitchen.dm line 241 - if ( istype(target,/obj/item)) - if ( !isturf(target.loc) ) // Don't load up stuff if it's inside a container or mob! - return - var turf/pickup = target.loc - - var addedSomething = 0 - - for(var/obj/item/weapon/reagent_containers/food/I in pickup) - - - if( I != src && !I.anchored && !istype(I, /obj/item/clothing/under) && !istype(I, /obj/item/clothing/suit) && !istype(I, /obj/item/projectile) ) - var/add = 0 - if(I.w_class == 1.0) - add = 1 - else if(I.w_class == 2.0) - add = 3 - else - add = 5 - if(calc_carry() + add >= max_carry) - break - - I.loc = src - carrying.Add(I) - overlays += image("icon" = I.icon, "icon_state" = I.icon_state, "layer" = 30 + I.layer) - addedSomething = 1 - if ( addedSomething ) - user.visible_message("\blue [user] load some items onto their service tray.") - - return - - // Unloads the tray, copied from base item's proc dropped() and altered - // see code\game\objects\items\weapons\kitchen.dm line 263 - - if ( isturf(target) || istype(target,/obj/structure/table) ) - var foundtable = istype(target,/obj/structure/table/) - if ( !foundtable ) //it must be a turf! - for(var/obj/structure/table/T in target) - foundtable = 1 - break - - var turf/dropspot - if ( !foundtable ) // don't unload things onto walls or other silly places. - dropspot = user.loc - else if ( isturf(target) ) // they clicked on a turf with a table in it - dropspot = target - else // they clicked on a table - dropspot = target.loc - - - overlays = null - - var droppedSomething = 0 - - for(var/obj/item/I in carrying) - I.loc = dropspot - carrying.Remove(I) - droppedSomething = 1 - if(!foundtable && isturf(dropspot)) - // if no table, presume that the person just shittily dropped the tray on the ground and made a mess everywhere! - spawn() - for(var/i = 1, i <= rand(1,2), i++) - if(I) - step(I, pick(NORTH,SOUTH,EAST,WEST)) - sleep(rand(2,4)) - if ( droppedSomething ) - if ( foundtable ) - user.visible_message("\blue [user] unloads their service tray.") - else - user.visible_message("\blue [user] drops all the items on their tray.") - - return ..() - - - - -// A special pen for service droids. Can be toggled to switch between normal writting mode, and paper rename mode +// A special pen for service droids. Can be toggled to switch between normal writing mode, and paper rename mode // Allows service droids to rename paper items. /obj/item/weapon/pen/robopen diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 92a8f1fd557..580322a9517 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -4,12 +4,13 @@ icon_state = "std_module" w_class = 100.0 item_state = "electronic" - flags = FPRINT|TABLEPASS | CONDUCT + flags = CONDUCT var/list/modules = list() var/obj/item/emag = null var/obj/item/borg/upgrade/jetpack = null var/list/stacktypes + var/channels = list() emp_act(severity) @@ -56,6 +57,22 @@ if(O) modules += O +/obj/item/weapon/robot_module/proc/add_languages(var/mob/living/silicon/robot/R) + //full set of languages + R.add_language("Galactic Common", 1) + R.add_language("Sol Common", 1) + R.add_language("Tradeband", 1) + R.add_language("Gutter", 0) + R.add_language("Sinta'unathi", 0) + R.add_language("Siik'tajr", 0) + R.add_language("Skrellian", 0) + R.add_language("Vox-pidgin", 0) + R.add_language("Rootspeak", 0) + R.add_language("Trinary", 1) + R.add_language("Chittin", 0) + R.add_language("Bubblish", 0) + R.add_language("Clownish",0) + /obj/item/weapon/robot_module/standard name = "standard robot module" @@ -71,10 +88,12 @@ src.emag = new /obj/item/weapon/melee/energy/sword/cyborg(src) return -/obj/item/weapon/robot_module/surgeon - name = "surgeon robot module" +/obj/item/weapon/robot_module/medical + name = "medical robot module" stacktypes = list( /obj/item/stack/medical/advanced/bruise_pack = 5, + /obj/item/stack/medical/advanced/ointment = 5, + /obj/item/stack/medical/splint = 5, /obj/item/stack/nanopaste = 5 ) @@ -82,7 +101,18 @@ src.modules += new /obj/item/device/flashlight(src) src.modules += new /obj/item/device/flash/cyborg(src) src.modules += new /obj/item/device/healthanalyzer(src) - src.modules += new /obj/item/weapon/reagent_containers/borghypo/surgeon(src) + src.modules += new /obj/item/device/reagent_scanner/adv(src) + src.modules += new /obj/item/weapon/borg_defib(src) + src.modules += new /obj/item/roller_holder(src) + src.modules += new /obj/item/weapon/reagent_containers/borghypo(src) + src.modules += new /obj/item/weapon/reagent_containers/glass/beaker/large(src) + src.modules += new /obj/item/weapon/reagent_containers/dropper(src) + src.modules += new /obj/item/weapon/reagent_containers/syringe(src) + src.modules += new /obj/item/weapon/extinguisher/mini(src) + src.modules += new /obj/item/stack/medical/advanced/bruise_pack(src) + src.modules += new /obj/item/stack/medical/advanced/ointment(src) + src.modules += new /obj/item/stack/medical/splint(src) + src.modules += new /obj/item/stack/nanopaste(src) src.modules += new /obj/item/weapon/scalpel(src) src.modules += new /obj/item/weapon/hemostat(src) src.modules += new /obj/item/weapon/retractor(src) @@ -92,9 +122,6 @@ src.modules += new /obj/item/weapon/bonesetter(src) src.modules += new /obj/item/weapon/circular_saw(src) src.modules += new /obj/item/weapon/surgicaldrill(src) - src.modules += new /obj/item/weapon/extinguisher/mini(src) - src.modules += new /obj/item/stack/medical/advanced/bruise_pack(src) - src.modules += new /obj/item/stack/nanopaste(src) src.emag = new /obj/item/weapon/reagent_containers/spray(src) @@ -102,59 +129,12 @@ src.emag.name = "Polyacid spray" return -/obj/item/weapon/robot_module/surgeon/respawn_consumable(var/mob/living/silicon/robot/R) +/obj/item/weapon/robot_module/medical/respawn_consumable(var/mob/living/silicon/robot/R) if(src.emag) var/obj/item/weapon/reagent_containers/spray/PS = src.emag PS.reagents.add_reagent("pacid", 2) ..() -/obj/item/weapon/robot_module/crisis - name = "crisis robot module" - stacktypes = list( - /obj/item/stack/medical/advanced/ointment = 5, - /obj/item/stack/medical/advanced/bruise_pack = 5, - /obj/item/stack/medical/splint = 5 - ) - - - New() - src.modules += new /obj/item/device/flashlight(src) - src.modules += new /obj/item/device/flash/cyborg(src) - src.modules += new /obj/item/device/healthanalyzer(src) - src.modules += new /obj/item/device/reagent_scanner/adv(src) - src.modules += new /obj/item/roller_holder(src) - src.modules += new /obj/item/stack/medical/advanced/ointment(src) - src.modules += new /obj/item/stack/medical/advanced/bruise_pack(src) - src.modules += new /obj/item/stack/medical/splint(src) - src.modules += new /obj/item/weapon/reagent_containers/borghypo/crisis(src) - src.modules += new /obj/item/weapon/reagent_containers/glass/beaker/large(src) - src.modules += new /obj/item/weapon/reagent_containers/robodropper(src) - src.modules += new /obj/item/weapon/reagent_containers/syringe(src) - src.modules += new /obj/item/weapon/extinguisher/mini(src) - - src.emag = new /obj/item/weapon/reagent_containers/spray(src) - - src.emag.reagents.add_reagent("pacid", 250) - src.emag.name = "Polyacid spray" - var/obj/item/weapon/reagent_containers/spray/S = emag - S.banned_reagents = list() - return - -/obj/item/weapon/robot_module/crisis/respawn_consumable(var/mob/living/silicon/robot/R) - - var/obj/item/weapon/reagent_containers/syringe/S = locate() in src.modules - if(S.mode == 2) - S.reagents.clear_reagents() - S.mode = initial(S.mode) - S.desc = initial(S.desc) - S.update_icon() - - if(src.emag) - var/obj/item/weapon/reagent_containers/spray/PS = src.emag - PS.reagents.add_reagent("pacid", 2) - - ..() - /obj/item/weapon/robot_module/engineering name = "engineering robot module" @@ -220,11 +200,11 @@ New() src.modules += new /obj/item/device/flashlight/seclite(src) src.modules += new /obj/item/device/flash/cyborg(src) - src.modules += new /obj/item/weapon/handcuffs/cyborg(src) + src.modules += new /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg(src) src.modules += new /obj/item/weapon/melee/baton/robot(src) src.modules += new /obj/item/weapon/gun/energy/disabler/cyborg(src) src.modules += new /obj/item/taperoll/police(src) - src.modules += new /obj/item/device/taperecorder(src) + src.modules += new /obj/item/clothing/mask/gas/sechailer/cyborg(src) src.emag = new /obj/item/weapon/gun/energy/laser/cyborg(src) return @@ -237,7 +217,7 @@ src.modules += new /obj/item/device/flashlight(src) src.modules += new /obj/item/device/flash/cyborg(src) src.modules += new /obj/item/weapon/soap/nanotrasen(src) - src.modules += new /obj/item/weapon/storage/bag/trash(src) + src.modules += new /obj/item/weapon/storage/bag/trash/cyborg(src) src.modules += new /obj/item/weapon/mop(src) src.modules += new /obj/item/device/lightreplacer(src) src.modules += new /obj/item/weapon/holosign_creator(src) @@ -268,7 +248,7 @@ src.modules += new /obj/item/weapon/reagent_containers/robodropper(src) src.modules += new /obj/item/weapon/lighter/zippo(src) - src.modules += new /obj/item/weapon/tray/robotray(src) + src.modules += new /obj/item/weapon/storage/bag/tray/cyborg(src) src.modules += new /obj/item/weapon/reagent_containers/food/drinks/shaker(src) src.emag = new /obj/item/weapon/reagent_containers/food/drinks/cans/beer(src) @@ -286,6 +266,22 @@ var/obj/item/weapon/reagent_containers/food/drinks/cans/beer/B = src.emag B.reagents.add_reagent("beer2", 2) +/obj/item/weapon/robot_module/butler/add_languages(var/mob/living/silicon/robot/R) + //full set of languages + R.add_language("Galactic Common", 1) + R.add_language("Sol Common", 1) + R.add_language("Tradeband", 1) + R.add_language("Gutter", 1) + R.add_language("Sinta'unathi", 1) + R.add_language("Siik'tajr", 1) + R.add_language("Skrellian", 1) + R.add_language("Vox-pidgin", 1) + R.add_language("Rootspeak", 1) + R.add_language("Trinary", 1) + R.add_language("Chittin", 1) + R.add_language("Bubblish", 1) + R.add_language("Clownish",1) + /* /obj/item/weapon/robot_module/clerical //Whyyyyy? name = "clerical robot module" @@ -338,8 +334,7 @@ src.modules += new /obj/item/device/flash/cyborg(src) src.modules += new /obj/item/device/flashlight(src) src.modules += new /obj/item/weapon/melee/energy/sword/cyborg(src) - src.modules += new /obj/item/weapon/gun/energy/printer(src) - src.modules += new /obj/item/weapon/gun/projectile/revolver/grenadelauncher/multi/cyborg(src) + src.modules += new /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow/large/cyborg(src) src.modules += new /obj/item/weapon/card/emag(src) src.modules += new /obj/item/weapon/tank/jetpack/carbondioxide(src) src.modules += new /obj/item/weapon/crowbar(src) @@ -379,6 +374,10 @@ src.emag.reagents.add_reagent("pacid", 125) src.emag.reagents.add_reagent("sacid", 125) +/obj/item/weapon/robot_module/alien/hunter/add_languages(var/mob/living/silicon/robot/R) + ..() + R.add_language("xenocommon", 1) + /obj/item/weapon/robot_module/drone name = "drone module" stacktypes = list( diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm index 35a31a8dbe0..ba5b0ad4f82 100644 --- a/code/modules/mob/living/silicon/say.dm +++ b/code/modules/mob/living/silicon/say.dm @@ -2,79 +2,154 @@ var/ending = copytext(text, length(text)) if (ending == "?") - return "[speak_query], \"[text]\""; + return speak_query else if (ending == "!") - return "[speak_exclamation], \"[text]\""; + return speak_exclamation - return "[speak_statement], \"[text]\""; + return speak_statement + +#define IS_AI 1 +#define IS_ROBOT 2 +#define IS_PAI 3 + +/mob/living/silicon/say_understands(var/other,var/datum/language/speaking = null) + //These only pertain to common. Languages are handled by mob/say_understands() + if (!speaking) + if (istype(other, /mob/living/carbon)) + return 1 + if (istype(other, /mob/living/silicon)) + return 1 + if (istype(other, /mob/living/carbon/brain)) + return 1 + return ..() /mob/living/silicon/say(var/message) if (!message) - return + return 0 if (src.client) if(client.prefs.muted & MUTE_IC) src << "You cannot send IC messages (muted)." - return + return 0 if (src.client.handle_spam_prevention(message,MUTE_IC)) - return + return 0 + + message = trim_strip_html_properly(message) if (stat == 2) - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) return say_dead(message) + if(copytext(message,1,2) == "*") + return emote(copytext(message,2)) + + var/bot_type = 0 //Let's not do a fuck ton of type checks, thanks. + if(istype(src, /mob/living/silicon/ai)) + bot_type = IS_AI + else if(istype(src, /mob/living/silicon/robot)) + bot_type = IS_ROBOT + else if(istype(src, /mob/living/silicon/pai)) + bot_type = IS_PAI + + var/mob/living/silicon/ai/AI = src //and let's not declare vars over and over and over for these guys. + var/mob/living/silicon/robot/R = src + var/mob/living/silicon/pai/P = src + //Must be concious to speak if (stat) - return + return 0 - if (length(message) >= 2) - var/prefix = copytext(message, 1, 3) - if (department_radio_keys[prefix] == "binary") - if(istype(src, /mob/living/silicon/pai)) - return ..(message) - message = copytext(message, 3) - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) + var/verb = say_quote(message) - // TODO: move the component system up to silicon so we don't have to use this ugly hack.. - if(istype(src, /mob/living/silicon/robot)) - var/mob/living/silicon/robot/R = src - if(!R.is_component_functioning("comms")) - src << "\red Your binary communications component isn't functional." - return - robot_talk(message) - - else if (department_radio_keys[prefix] == "alientalk") - if(!alien_talk_understand) return - message = copytext(message, 3) - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) - - alien_talk(message) - else if (department_radio_keys[prefix] == "department") - if(isAI(src)&&client) //For patching directly into AI holopads. - var/mob/living/silicon/ai/U = src - message = copytext(message, 3) - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) - U.holopad_talk(message) - else //Will not allow anyone by an active AI to use this function. - src << "This function is not available to you." - return + //parse radio key and consume it + var/message_mode = parse_message_mode(message, "general") + if (message_mode) + if (message_mode == "general") + message = trim(copytext(message,2)) else - var/mob/living/silicon/ai/AI = src - if (isAI(src) && AI.aiRadio.disabledAi) - src << "\red System Error - Transceiver Disabled" - return - else - return ..(message) - else - var/mob/living/silicon/ai/AI = src - if (isAI(src) && AI.aiRadio.disabledAi) - src << "\red System Error - Transceiver Disabled" - return + message = trim(copytext(message,3)) + + //parse language key and consume it + var/datum/language/speaking = parse_language(message) + if (speaking) + verb = speaking.speech_verb + message = trim(copytext(message,2+length(speaking.key))) + + if(speaking.flags & HIVEMIND) + speaking.broadcast(src,trim(message)) + return 1 + + // Currently used by drones. + if(local_transmit) + var/list/listeners = hearers(5,src) + listeners |= src + + for(var/mob/living/silicon/D in listeners) + if(D.client && istype(D,src.type)) + D << "[src] transmits, \"[message]\"" + + for (var/mob/M in player_list) + if (istype(M, /mob/new_player)) + continue + else if(M.stat == 2 && M.client.prefs.toggles & CHAT_GHOSTEARS) + if(M.client) M << "[src] transmits, \"[message]\"" + return 1 + + if(message_mode && bot_type == IS_ROBOT && !R.is_component_functioning("radio")) + src << "\red Your radio isn't functional at this time." + return 0 + + switch(message_mode) + if("department") + switch(bot_type) + if(IS_AI) + return AI.holopad_talk(message, verb, speaking) + if(IS_ROBOT) + log_say("[key_name(src)] : [message]") + return R.radio.talk_into(src,message,message_mode,verb,speaking) + if(IS_PAI) + log_say("[key_name(src)] : [message]") + return P.radio.talk_into(src,message,message_mode,verb,speaking) + return 0 + + if("general") + switch(bot_type) + if(IS_AI) + if (AI.aiRadio.disabledAi || AI.aiRestorePowerRoutine || AI.stat) + src << "\red System Error - Transceiver Disabled" + return 0 + else + log_say("[key_name(src)] : [message]") + return AI.aiRadio.talk_into(src,message,null,verb,speaking) + if(IS_ROBOT) + log_say("[key_name(src)] : [message]") + return R.radio.talk_into(src,message,null,verb,speaking) + if(IS_PAI) + log_say("[key_name(src)] : [message]") + return P.radio.talk_into(src,message,null,verb,speaking) + return 0 + else - return ..(message) + if(message_mode) + switch(bot_type) + if(IS_AI) + if (AI.aiRadio.disabledAi || AI.aiRestorePowerRoutine || AI.stat) + src << "\red System Error - Transceiver Disabled" + return 0 + else + log_say("[key_name(src)] : [message]") + return AI.aiRadio.talk_into(src,message,message_mode,verb,speaking) + if(IS_ROBOT) + log_say("[key_name(src)] : [message]") + return R.radio.talk_into(src,message,message_mode,verb,speaking) + if(IS_PAI) + log_say("[key_name(src)] : [message]") + return P.radio.talk_into(src,message,message_mode,verb,speaking) + return 0 + + return ..(message,speaking,verb) //For holopads only. Usable by AI. -/mob/living/silicon/ai/proc/holopad_talk(var/message) +/mob/living/silicon/ai/proc/holopad_talk(var/message, verb, datum/language/speaking) log_say("[key_name(src)] : [message]") @@ -84,18 +159,23 @@ return var/obj/machinery/hologram/holopad/T = src.holo - if(istype(T) && T.hologram && T.master == src)//If there is a hologram and its master is the user. - var/message_a = say_quote(message) + if(T && T.hologram && T.master == src)//If there is a hologram and its master is the user. //Human-like, sorta, heard by those who understand humans. - var/rendered_a = "[name] [message_a]" - + var/rendered_a //Speach distorted, heard by those who do not understand AIs. - message = stars(message) - var/message_b = say_quote(message) - var/rendered_b = "[voice_name] [message_b]" + var/message_stars = stars(message) + var/rendered_b + + if(speaking) + rendered_a = "[name] [speaking.format_message(message, verb)]" + rendered_b = "[voice_name] [speaking.format_message(message_stars, verb)]" + src << "Holopad transmitted, [real_name] [speaking.format_message(message, verb)]"//The AI can "hear" its own message. + else + rendered_a = "[name] [verb], \"[message]\"" + rendered_b = "[voice_name] [verb], \"[message_stars]\"" + src << "Holopad transmitted, [real_name] [verb], \"[message]\""//The AI can "hear" its own message. - src << "Holopad transmitted, [real_name] [message_a]"//The AI can "hear" its own message. for(var/mob/M in hearers(T.loc))//The location is the object, default distance. if(M.say_understands(src))//If they understand AI speak. Humans and the like will be able to. M.show_message(rendered_a, 2) @@ -105,79 +185,37 @@ This is another way of saying that we won't bother dealing with them.*/ else src << "No holopad connected." - return + return + return 1 -/mob/living/proc/robot_talk(var/message) +/mob/living/silicon/ai/proc/holopad_emote(var/message) //This is called when the AI uses the 'me' verb while using a holopad. - log_say("[key_name(src)] : [message]") - - var/desig = "Unknown" //ezmode for taters - if(isrobot(src)) - var/mob/living/silicon/S = src - if(S.designation) - desig = trim_left(S.designation) - else - desig = "Default" - else if(isAI(src)) - desig = "AI" + log_emote("[key_name(src)] : [message]") message = trim(message) if (!message) return - var/message_a = say_quote(message) - var/rendered = "Robotic Talk, [name] ([desig]) [message_a]" + var/obj/machinery/hologram/holopad/T = src.holo + if(T && T.hologram && T.master == src) + var/rendered = "[name] [message]" + src << "Holopad action relayed, [real_name] [message]" - for (var/mob/living/S in living_mob_list) - if(S.robot_talk_understand && (S.robot_talk_understand == robot_talk_understand)) // This SHOULD catch everything caught by the one below, but I'm not going to change it. - if(istype(S , /mob/living/silicon/ai)) - var/renderedAI = "Robotic Talk, [name] ([desig]) [message_a]" - S.show_message(renderedAI, 2) - else if(istype(S , /mob/dead/observer) && S.stat == DEAD) - var/rendered2 = "Robotic Talk, [name] ([desig]) (Follow) [message_a]" - S.show_message(rendered2, 2) - else - S.show_message(rendered, 2) - - - else if (S.binarycheck()) - if(istype(S , /mob/living/silicon/ai)) - var/renderedAI = "Robotic Talk, [name] [message_a]" - S.show_message(renderedAI, 2) - else if(istype(S , /mob/dead/observer) && S.stat == DEAD) - var/rendered2 = "Robotic Talk, [name] (Follow) [message_a]" - S.show_message(rendered2, 2) - else - S.show_message(rendered, 2) - - var/list/listening = hearers(1, src) - listening -= src - listening += src - - var/list/heard = list() - for (var/mob/M in listening) - if(!istype(M, /mob/living/silicon) && !M.robot_talk_understand) - heard += M - - if (length(heard)) - var/message_b - - message_b = "beep beep beep" - message_b = say_quote(message_b) - message_b = "[message_b]" - - rendered = "[voice_name] [message_b]" - - for (var/mob/M in heard) + for(var/mob/M in viewers(T.loc)) M.show_message(rendered, 2) + else //This shouldn't occur, but better safe then sorry. + src << "No holopad connected." + return + return 1 - message = say_quote(message) +/mob/living/silicon/ai/emote(var/act, var/type, var/message) + var/obj/machinery/hologram/holopad/T = src.holo + if(T && T.hologram && T.master == src) //Is the AI using a holopad? + src.holopad_emote(message) + else //Emote normally, then. + ..() -// rendered = "Robotic Talk, [name] [message_a]" - rendered = null - - for (var/mob/M in dead_mob_list) - if(!istype(M,/mob/new_player) && !istype(M,/mob/living/carbon/brain)) //No meta-evesdropping - rendered = "Robotic Talk, [name] (Follow) [message_a]" - M.show_message(rendered, 2) \ No newline at end of file +#undef IS_AI +#undef IS_ROBOT +#undef IS_PAI diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 6f88c99c71e..1c8e7b71d65 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -8,6 +8,7 @@ var/list/alarms_to_clear = list() immune_to_ssd = 1 var/list/hud_list[10] + var/list/speech_synthesizer_langs = list() //which languages can be vocalized by the speech synthesizer var/list/alarm_types_show = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0) var/list/alarm_types_clear = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0) var/designation = "" @@ -20,6 +21,8 @@ var/sensor_mode = 0 //Determines the current HUD. #define SEC_HUD 1 //Security HUD mode #define MED_HUD 2 //Medical HUD mode + var/local_transmit //If set, can only speak to others of the same type within a short range. + var/obj/item/device/radio/common_radio /mob/living/silicon/proc/cancelAlarm() return @@ -122,6 +125,11 @@ /mob/living/silicon/proc/damage_mob(var/brute = 0, var/fire = 0, var/tox = 0) return +/mob/living/silicon/can_inject(var/mob/user, var/error_msg) + if(error_msg) + user << "Their outer shell is too tough." + return 0 + /mob/living/silicon/IsAdvancedToolUser() return 1 @@ -206,6 +214,37 @@ show_system_integrity() show_malf_ai() +//Silicon mob language procs + +/mob/living/silicon/can_speak(datum/language/speaking) + return universal_speak || (speaking in src.speech_synthesizer_langs) //need speech synthesizer support to vocalize a language + +/mob/living/silicon/add_language(var/language, var/can_speak=1) + if (..(language) && can_speak) + speech_synthesizer_langs.Add(all_languages[language]) + return 1 + +/mob/living/silicon/remove_language(var/rem_language) + ..(rem_language) + + for (var/datum/language/L in speech_synthesizer_langs) + if (L.name == rem_language) + speech_synthesizer_langs -= L + +/mob/living/silicon/check_languages() + set name = "Check Known Languages" + set category = "IC" + set src = usr + + var/dat = "Known Languages

" + + for(var/datum/language/L in languages) + if(!(L.flags & NONGLOBAL)) + dat += "[L.name] (:[L.key])
Speech Synthesizer: [(L in speech_synthesizer_langs)? "YES":"NOT SUPPORTED"]
[L.desc]

" + + src << browse(dat, "window=checklanguage") + return + // this function displays the stations manifest in a separate window /mob/living/silicon/proc/show_station_manifest() var/dat @@ -249,14 +288,17 @@ set desc = "Sets a description which will be shown when someone examines you." set category = "IC" - pose = copytext(sanitize(input(usr, "This is [src]. It is...", "Pose", null) as text), 1, MAX_MESSAGE_LEN) + pose = sanitize(copytext(input(usr, "This is [src]. It is...", "Pose", null) as text, 1, MAX_MESSAGE_LEN)) /mob/living/silicon/verb/set_flavor() set name = "Set Flavour Text" set desc = "Sets an extended description of your character's features." set category = "IC" - flavor_text = copytext(sanitize(input(usr, "Please enter your new flavour text.", "Flavour text", null) as text), 1) + flavor_text = sanitize(copytext(input(usr, "Please enter your new flavour text.", "Flavour text", null) as text, 1)) + +/mob/living/silicon/binarycheck() + return 1 /mob/living/silicon/proc/toggle_sensor_mode() var/sensor_type = input("Please select sensor type.", "Sensor Integration", null) in list("Security", "Medical","Disable") diff --git a/code/modules/mob/living/simple_animal/borer.dm b/code/modules/mob/living/simple_animal/borer.dm index 8dae4be093b..f8dd9e5c6fe 100644 --- a/code/modules/mob/living/simple_animal/borer.dm +++ b/code/modules/mob/living/simple_animal/borer.dm @@ -12,7 +12,7 @@ return if(istype(src.loc,/mob/living/simple_animal/borer)) - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) + message = trim(sanitize(copytext(message, 1, MAX_MESSAGE_LEN))) if (!message) return log_say("[key_name(src)] : [message]") @@ -100,51 +100,12 @@ /mob/living/simple_animal/borer/New(var/by_gamemode=0) ..() + add_language("Cortical Link") truename = "[pick("Primary","Secondary","Tertiary","Quaternary")] [rand(1000,9999)]" if(!by_gamemode) request_player() - -/mob/living/simple_animal/borer/say(var/message) - - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) - message = capitalize(message) - - if(!message) - return - - if (stat == 2) - return say_dead(message) - - if (stat) - return - - if (src.client) - if(client.prefs.muted & MUTE_IC) - src << "\red You cannot speak in IC (muted)." - return - if (src.client.handle_spam_prevention(message,MUTE_IC)) - return - - if (copytext(message, 1, 2) == "*") - return emote(copytext(message, 2)) - - if (copytext(message, 1, 2) == ";") //Brain borer hivemind. - return borer_speak(message) - - if(!host) - src << "You have no host to speak to." - return //No host, no audible speech. - - src << "You drop words into [host]'s mind: \"[message]\"" - host << "Your own thoughts speak: \"[message]\"" - - for(var/mob/M in mob_list) - if(M.mind && (istype(M, /mob/dead/observer))) - M << "Thought-speech, [truename] -> [host]: [copytext(message, 2)]" - - /mob/living/simple_animal/borer/Stat() ..() statpanel("Status") diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index 0c8f61569b4..c54c1329707 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -66,7 +66,7 @@ now_pushing = 1 if(ismob(AM)) var/mob/tmob = AM - if(istype(tmob, /mob/living/carbon/human) && (M_FAT in tmob.mutations)) + if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) if(prob(5)) src << "\red You fail to push [tmob]'s fat ass out of the way." now_pushing = 0 @@ -101,6 +101,7 @@ if(M.melee_damage_upper <= 0) M.emote("[M.friendly] \the [src]") else + M.do_attack_animation(src) if(M.attack_sound) playsound(loc, M.attack_sound, 50, 1, 1) for(var/mob/O in viewers(src, null)) @@ -109,7 +110,7 @@ var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) adjustBruteLoss(damage) -/mob/living/simple_animal/construct/attackby(var/obj/item/O as obj, var/mob/user as mob) +/mob/living/simple_animal/construct/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(O.force) var/damage = O.force if (O.damtype == STAMINA) @@ -150,7 +151,7 @@ status_flags = 0 construct_spells = list(/obj/effect/proc_holder/spell/wizard/aoe_turf/conjure/lesserforcewall) -/mob/living/simple_animal/construct/armoured/attackby(var/obj/item/O as obj, var/mob/user as mob) +/mob/living/simple_animal/construct/armoured/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(O.force) if(O.force >= 11) var/damage = O.force @@ -279,7 +280,7 @@ var/energy = 0 var/max_energy = 1000 -/mob/living/simple_animal/construct/behemoth/attackby(var/obj/item/O as obj, var/mob/user as mob) +/mob/living/simple_animal/construct/behemoth/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(O.force) if(O.force >= 11) var/damage = O.force diff --git a/code/modules/mob/living/simple_animal/friendly/butterfly.dm b/code/modules/mob/living/simple_animal/friendly/butterfly.dm new file mode 100644 index 00000000000..4c4841a77e9 --- /dev/null +++ b/code/modules/mob/living/simple_animal/friendly/butterfly.dm @@ -0,0 +1,21 @@ +/mob/living/simple_animal/butterfly + name = "butterfly" + desc = "A colorful butterfly, how'd it get up here?" + icon_state = "butterfly" + icon_living = "butterfly" + icon_dead = "butterfly_dead" + turns_per_move = 1 + emote_see = list("flutters") + response_help = "shoos" + response_disarm = "brushes aside" + response_harm = "aquashes" + speak_chance = 0 + maxHealth = 2 + health = 2 + harm_intent_damage = 1 + friendly = "nudges" + pass_flags = PASSTABLE + +/mob/living/simple_animal/butterfly/New() + ..() + color = rgb(rand(0, 255), rand(0, 255), rand(0, 255)) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/friendly/corgi.dm b/code/modules/mob/living/simple_animal/friendly/corgi.dm index 9b638505e28..23c5f23af80 100644 --- a/code/modules/mob/living/simple_animal/friendly/corgi.dm +++ b/code/modules/mob/living/simple_animal/friendly/corgi.dm @@ -7,6 +7,8 @@ icon_state = "corgi" icon_living = "corgi" icon_dead = "corgi_dead" + health = 30 + maxHealth = 30 speak = list("YAP", "Woof!", "Bark!", "AUUUUUU") speak_emote = list("barks", "woofs") emote_hear = list("barks", "woofs", "yaps","pants") @@ -25,7 +27,43 @@ var/obj/item/inventory_back var/facehugger +/mob/living/simple_animal/corgi/New() + ..() + regenerate_icons() + /mob/living/simple_animal/corgi/Life() + . = ..() + if(.) + if(fire) + if(fire_alert) fire.icon_state = "fire[fire_alert]" //fire_alert is either 0 if no alert, 1 for heat and 2 for cold. + else fire.icon_state = "fire0" + if(pullin) + if(pulling) pullin.icon_state = "pull1" + else pullin.icon_state = "pull0" + if(oxygen) + if(oxygen_alert) oxygen.icon_state = "oxy1" + else oxygen.icon_state = "oxy0" + if(toxin) + if(toxins_alert) toxin.icon_state = "tox1" + else toxin.icon_state = "tox0" + + if (healths) + switch(health) + if(30 to INFINITY) healths.icon_state = "health0" + if(26 to 29) healths.icon_state = "health1" + if(21 to 25) healths.icon_state = "health2" + if(16 to 20) healths.icon_state = "health3" + if(11 to 15) healths.icon_state = "health4" + if(6 to 10) healths.icon_state = "health5" + if(1 to 5) healths.icon_state = "health6" + else healths.icon_state = "health7" + regenerate_icons() + +/mob/living/simple_animal/corgi/Die() + ..() + regenerate_icons() + +/mob/living/simple_animal/corgi/revive() ..() regenerate_icons() @@ -33,7 +71,7 @@ user.set_machine(src) if(user.stat) return - var/dat = "
Inventory of [name]

" + var/dat = "

Inventory of [real_name]

" if(inventory_head) dat += "
Head: [inventory_head] (Remove)" else @@ -47,7 +85,7 @@ onclose(user, "mob[real_name]") return -/mob/living/simple_animal/corgi/attackby(var/obj/item/O as obj, var/mob/user as mob) +/mob/living/simple_animal/corgi/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(inventory_head && inventory_back) //helmet and armor = 100% protection if( istype(inventory_head,/obj/item/clothing/head/helmet) && istype(inventory_back,/obj/item/clothing/suit/armor) ) @@ -85,6 +123,7 @@ SetLuminosity(0) inventory_head.loc = src.loc inventory_head = null + regenerate_icons() else usr << "\red There is nothing to remove from its [remove_from]." return @@ -92,6 +131,7 @@ if(inventory_back) inventory_back.loc = src.loc inventory_back = null + regenerate_icons() else usr << "\red There is nothing to remove from its [remove_from]." return @@ -163,6 +203,7 @@ usr.drop_item() place_on_head(item_to_add) + regenerate_icons() if("back") if(inventory_back) @@ -281,7 +322,7 @@ ..() //Feeding, chasing food, FOOOOODDDD - if(!stat && !resting && !buckled) + if(!stat && !resting && !buckled && (ckey == null)) turns_since_scan++ if(turns_since_scan > 5) turns_since_scan = 0 @@ -325,9 +366,10 @@ if(prob(1)) emote(pick("dances around","chases its tail")) spawn(0) - for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2)) - dir = i - sleep(1) + if (ckey == null) + for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2)) + dir = i + sleep(1) /obj/item/weapon/reagent_containers/food/snacks/meat/corgi name = "Corgi meat" @@ -341,7 +383,7 @@ now_pushing = 1 if(ismob(AM)) var/mob/tmob = AM - if(istype(tmob, /mob/living/carbon/human) && (M_FAT in tmob.mutations)) + if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) if(prob(70)) src << "\red You fail to push [tmob]'s fat ass out of the way." now_pushing = 0 @@ -376,14 +418,15 @@ if ((M.client && !( M.blinded ))) M.show_message("\blue [user] baps [name] on the nose with the rolled up [O]") spawn(0) - for(var/i in list(1,2,4,8,4,2,1,2)) - dir = i - sleep(1) + if (ckey == null) + for(var/i in list(1,2,4,8,4,2,1,2)) + dir = i + sleep(1) else ..() /mob/living/simple_animal/corgi/regenerate_icons() - overlays = list() + overlays.Cut() if(inventory_head) var/head_icon_state = inventory_head.icon_state @@ -456,11 +499,12 @@ if(!stat && !resting && !buckled) if(prob(1)) - emote(pick("dances around","chases her tail")) - spawn(0) - for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2)) - dir = i - sleep(1) + if (ckey == null) + emote(pick("dances around","chases her tail")) + spawn(0) + for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2)) + dir = i + sleep(1) /mob/living/simple_animal/corgi/Ian/borgi @@ -471,14 +515,12 @@ icon_living = "borgi" var/emagged = 0 -/mob/living/simple_animal/corgi/Ian/borgi/attackby(var/obj/item/O as obj, var/mob/user as mob) - if (istype(O, /obj/item/weapon/card/emag) && !emagged) +/mob/living/simple_animal/corgi/Ian/borgi/emag_act(user as mob) + if(!emagged) emagged = 1 visible_message("[user] swipes a card through [src].", "You overload [src]s internal reactor.") spawn (1000) src.explode() - return - ..() /mob/living/simple_animal/corgi/Ian/borgi/proc/explode() for(var/mob/M in viewers(src, null)) diff --git a/code/modules/mob/living/simple_animal/friendly/corgi_powers.dm b/code/modules/mob/living/simple_animal/friendly/corgi_powers.dm new file mode 100644 index 00000000000..ad945390cd1 --- /dev/null +++ b/code/modules/mob/living/simple_animal/friendly/corgi_powers.dm @@ -0,0 +1,11 @@ +/mob/living/simple_animal/corgi/verb/chasetail() + set name = "Chase your tail" + set desc = "d'awwww." + set category = "Corgi" + src << text("[pick("You dance around","You chase your tail")].") + for(var/mob/O in oviewers(src, null)) + if ((O.client && !( O.blinded ))) + O << text("[] [pick("dances around","chases its tail")].", src) + for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2)) + dir = i + sleep(1) diff --git a/code/modules/mob/living/simple_animal/friendly/crab.dm b/code/modules/mob/living/simple_animal/friendly/crab.dm index cb5378b8bbf..6d8064d6132 100644 --- a/code/modules/mob/living/simple_animal/friendly/crab.dm +++ b/code/modules/mob/living/simple_animal/friendly/crab.dm @@ -42,7 +42,7 @@ response_harm = "stomps" //LOOK AT THIS - ..()?? -/*/mob/living/simple_animal/crab/attackby(var/obj/item/O as obj, var/mob/user as mob) +/*/mob/living/simple_animal/crab/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(istype(O, /obj/item/weapon/wirecutters)) if(prob(50)) user << "\red \b This kills the crab." diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index cc7a6ea4028..7c27348a7e7 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -72,8 +72,9 @@ if(prob(10)) say("Nom") -/mob/living/simple_animal/hostile/retaliate/goat/attackby(var/obj/item/O as obj, var/mob/user as mob) +/mob/living/simple_animal/hostile/retaliate/goat/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(stat == CONSCIOUS && istype(O, /obj/item/weapon/reagent_containers/glass)) + user.changeNext_move(CLICK_CD_MELEE) user.visible_message("[user] milks [src] using \the [O].") var/obj/item/weapon/reagent_containers/glass/G = O var/transfered = udder.trans_id_to(G, "milk", rand(5,10)) @@ -112,7 +113,7 @@ udder.my_atom = src ..() -/mob/living/simple_animal/cow/attackby(var/obj/item/O as obj, var/mob/user as mob) +/mob/living/simple_animal/cow/attackby(var/obj/item/O as obj, var/mob/user as mob, params, params) if(stat == CONSCIOUS && istype(O, /obj/item/weapon/reagent_containers/glass)) user.visible_message("[user] milks [src] using \the [O].") var/obj/item/weapon/reagent_containers/glass/G = O @@ -229,7 +230,7 @@ var/global/chicken_count = 0 ..() chicken_count -= 1 -/mob/living/simple_animal/chicken/attackby(var/obj/item/O as obj, var/mob/user as mob) +/mob/living/simple_animal/chicken/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown/wheat)) //feedin' dem chickens if(!stat && eggsleft < 8) user.visible_message("\blue [user] feeds [O] to [name]! It clucks happily.","\blue You feed [O] to [name]! It clucks happily.") diff --git a/code/modules/mob/living/simple_animal/friendly/Fox.dm b/code/modules/mob/living/simple_animal/friendly/fox.dm similarity index 97% rename from code/modules/mob/living/simple_animal/friendly/Fox.dm rename to code/modules/mob/living/simple_animal/friendly/fox.dm index 095445069ca..da38c222b42 100644 --- a/code/modules/mob/living/simple_animal/friendly/Fox.dm +++ b/code/modules/mob/living/simple_animal/friendly/fox.dm @@ -30,4 +30,4 @@ icon_living = "Syndifox" icon_dead = "Syndifox_dead" flags = IS_SYNTHETIC|NO_BREATHE - faction = list("syndicate") \ No newline at end of file + faction = list("syndicate") diff --git a/code/modules/mob/living/simple_animal/friendly/pug.dm b/code/modules/mob/living/simple_animal/friendly/pug.dm new file mode 100644 index 00000000000..62456ed8a8b --- /dev/null +++ b/code/modules/mob/living/simple_animal/friendly/pug.dm @@ -0,0 +1,42 @@ +//Corgi //best comment 2014 +/mob/living/simple_animal/pug + name = "\improper pug" + real_name = "pug" + desc = "It's a pug." + icon_state = "pug" + icon_living = "pug" + icon_dead = "pug_dead" + speak = list("YAP", "Woof!", "Bark!", "AUUUUUU") + speak_emote = list("barks", "woofs") + emote_hear = list("barks!", "woofs!", "yaps.","pants.") + emote_see = list("shakes its head.", "chases its tail.","shivers.") + speak_chance = 1 + turns_per_move = 10 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/pug + meat_amount = 3 + response_help = "pets" + response_disarm = "bops" + response_harm = "kicks" + see_in_dark = 5 + +/mob/living/simple_animal/pug/Life() + ..() + + if(!stat && !resting && !buckled) + if(prob(1)) + emote("me", 1, pick("chases its tail.")) + spawn(0) + for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2)) + dir = i + sleep(1) + +/mob/living/simple_animal/pug/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri + if(istype(O, /obj/item/weapon/newspaper)) + if(!stat) + user.visible_message("[user] baps [name] on the nose with the rolled up [O]") + spawn(0) + for(var/i in list(1,2,4,8,4,2,1,2)) + dir = i + sleep(1) + else + ..() diff --git a/code/modules/mob/living/simple_animal/friendly/slime.dm b/code/modules/mob/living/simple_animal/friendly/slime.dm index ddddc43132a..df1fc75659d 100644 --- a/code/modules/mob/living/simple_animal/friendly/slime.dm +++ b/code/modules/mob/living/simple_animal/friendly/slime.dm @@ -23,7 +23,7 @@ now_pushing = 1 if(ismob(AM)) var/mob/tmob = AM - if(istype(tmob, /mob/living/carbon/human) && (M_FAT in tmob.mutations)) + if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) if(prob(70)) src << "\red You fail to push [tmob]'s fat ass out of the way." now_pushing = 0 diff --git a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm index 0854948bf6a..4729438839e 100644 --- a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm +++ b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm @@ -8,7 +8,7 @@ var/obj/item/device/radio/borg/radio = null var/mob/living/silicon/ai/connected_ai = null - var/obj/item/weapon/cell/cell = null + var/obj/item/weapon/stock_parts/cell/cell = null var/obj/machinery/camera/camera = null var/obj/item/device/mmi/mmi = null var/list/req_access = list(access_robotics) //Access needed to pop out the brain. @@ -42,7 +42,7 @@ speak_emote = list("beeps","clicks","chirps") can_hide = 1 -/mob/living/simple_animal/spiderbot/attackby(var/obj/item/O as obj, var/mob/user as mob) +/mob/living/simple_animal/spiderbot/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(istype(O, /obj/item/device/mmi) || istype(O, /obj/item/device/mmi/posibrain)) var/obj/item/device/mmi/B = O @@ -125,18 +125,6 @@ else user << "\red You swipe your card, with no effect." return 0 - else if (istype(O, /obj/item/weapon/card/emag)) - if (emagged) - user << "\red [src] is already overloaded - better run." - return 0 - else - var/obj/item/weapon/card/emag/emag = O - emag.uses-- - emagged = 1 - user << "\blue You short out the security protocols and overload [src]'s cell, priming it to explode in a short time." - spawn(100) src << "\red Your cell seems to be outputting a lot of power..." - spawn(200) src << "\red Internal heat sensors are spiking! Something is badly wrong with your cell!" - spawn(300) src.explode() else if(O.force) @@ -152,6 +140,17 @@ for(var/mob/M in viewers(src, null)) if ((M.client && !( M.blinded ))) M.show_message("\red [user] gently taps [src] with the [O]. ") + +/mob/living/simple_animal/spiderbot/emag_act(user as mob) + if (emagged) + user << "\red [src] is already overloaded - better run." + return 0 + else + emagged = 1 + user << "\blue You short out the security protocols and overload [src]'s cell, priming it to explode in a short time." + spawn(100) src << "\red Your cell seems to be outputting a lot of power..." + spawn(200) src << "\red Internal heat sensors are spiking! Something is badly wrong with your cell!" + spawn(300) src.explode() /mob/living/simple_animal/spiderbot/proc/transfer_personality(var/obj/item/device/mmi/M as obj) diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm index 287e24afe2c..d8f891d5c88 100644 --- a/code/modules/mob/living/simple_animal/hostile/bear.dm +++ b/code/modules/mob/living/simple_animal/hostile/bear.dm @@ -102,7 +102,7 @@ -/mob/living/simple_animal/hostile/bear/attackby(var/obj/item/O as obj, var/mob/user as mob) +/mob/living/simple_animal/hostile/bear/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(stance != HOSTILE_STANCE_ATTACK && stance != HOSTILE_STANCE_ATTACKING) stance = HOSTILE_STANCE_ALERT stance_step = 6 diff --git a/code/modules/mob/living/simple_animal/hostile/mushroom.dm b/code/modules/mob/living/simple_animal/hostile/mushroom.dm index e2d8bcd485c..5670f5e55de 100644 --- a/code/modules/mob/living/simple_animal/hostile/mushroom.dm +++ b/code/modules/mob/living/simple_animal/hostile/mushroom.dm @@ -120,7 +120,7 @@ src.visible_message("The [src.name] was bruised!") bruised = 1 -/mob/living/simple_animal/hostile/mushroom/attackby(obj/item/I as obj, mob/user as mob) +/mob/living/simple_animal/hostile/mushroom/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom)) if(stat == DEAD && !recovery_cooldown) Recover() diff --git a/code/modules/mob/living/simple_animal/hostile/russian.dm b/code/modules/mob/living/simple_animal/hostile/russian.dm index 743b5fd44b5..0da2e3bf84f 100644 --- a/code/modules/mob/living/simple_animal/hostile/russian.dm +++ b/code/modules/mob/living/simple_animal/hostile/russian.dm @@ -46,6 +46,10 @@ projectilesound = 'sound/weapons/Gunshot.ogg' casingtype = /obj/item/ammo_casing/a357 +/mob/living/simple_animal/hostile/russian/ranged/New() + if(prob(50) && ispath(weapon1,/obj/item/weapon/gun/projectile/revolver/mateba)) //to preserve varedits + weapon1 = /obj/item/weapon/gun/projectile/shotgun/boltaction + casingtype = /obj/item/ammo_casing/a762 /mob/living/simple_animal/hostile/russian/Die() ..() diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index df1f903f21f..c5c9c24b577 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -57,7 +57,7 @@ attacktext = "slashes" status_flags = 0 -/mob/living/simple_animal/hostile/syndicate/melee/attackby(var/obj/item/O as obj, var/mob/user as mob) +/mob/living/simple_animal/hostile/syndicate/melee/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(O.force) if(prob(80)) var/damage = O.force diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 810f1b0e384..1e5badbcdb0 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -48,6 +48,7 @@ response_disarm = "gently moves aside the" response_harm = "swats the" stop_automated_movement = 1 + universal_speak = 1 var/parrot_state = PARROT_WANDER //Hunt for a perch when created var/parrot_sleep_max = 25 //The time the parrot sits while perched before looking around. Mosly a way to avoid the parrot's AI in life() being run every single tick. @@ -61,7 +62,7 @@ var/list/available_channels = list() //Headset for Poly to yell at engineers :) - var/obj/item/device/radio/headset/l_ear = null + var/obj/item/device/radio/headset/ears = null //The thing the parrot is currently interested in. This gets used for items the parrot wants to pick up, mobs it wants to steal from, //mobs it wants to attack or mobs that have attacked it @@ -84,13 +85,13 @@ /mob/living/simple_animal/parrot/New() ..() - if(!l_ear) + if(!ears) var/headset = pick(/obj/item/device/radio/headset/headset_sec, \ /obj/item/device/radio/headset/headset_eng, \ /obj/item/device/radio/headset/headset_med, \ /obj/item/device/radio/headset/headset_sci, \ /obj/item/device/radio/headset/headset_cargo) - l_ear = new headset(src) + ears = new headset(src) parrot_sleep_dur = parrot_sleep_max //In case someone decides to change the max without changing the duration var @@ -100,7 +101,7 @@ /mob/living/simple_animal/parrot/proc/perch_player) -/mob/living/simple_animal/parrot/Die() +/mob/living/simple_animal/parrot/death() if(held_item) held_item.loc = src.loc held_item = null @@ -119,10 +120,10 @@ if(user.stat) return var/dat = "

Inventory of [name]

" - if(l_ear) - dat += "
Headset: [l_ear] (Remove)" + if(ears) + dat += "
Headset: [ears] (Remove)" else - dat += "
Headset: Nothing" + dat += "
Headset: Nothing" user << browse(dat, text("window=mob[];size=325x500", name)) onclose(user, "mob[real_name]") @@ -134,21 +135,21 @@ if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) return - //Is the usr's mob type able to do this? (lolaliens) - if(ishuman(usr) || ismonkey(usr) || isrobot(usr) || isalienadult(usr)) + //Is the usr's mob type able to do this? + if(ishuman(usr) || ismonkey(usr) || isrobot(usr)) //Removing from inventory if(href_list["remove_inv"]) var/remove_from = href_list["remove_inv"] switch(remove_from) - if("l_ear") - if(l_ear) + if("ears") + if(ears) if(available_channels.len) src.say("[pick(available_channels)] BAWWWWWK LEAVE THE HEADSET BAWKKKKK!") else src.say("BAWWWWWK LEAVE THE HEADSET BAWKKKKK!") - l_ear.loc = src.loc - l_ear = null + ears.loc = src.loc + ears = null for(var/possible_phrase in speak) if(copytext(possible_phrase,1,3) in department_radio_keys) possible_phrase = copytext(possible_phrase,3,length(possible_phrase)) @@ -163,8 +164,8 @@ usr << "\red You have nothing in your hand to put on its [add_to]." return switch(add_to) - if("l_ear") - if(l_ear) + if("ears") + if(ears) usr << "\red It's already wearing something." return else @@ -180,7 +181,7 @@ usr.drop_item() headset_to_add.loc = src - src.l_ear = headset_to_add + src.ears = headset_to_add usr << "You fit the headset onto [src]." clearlist(available_channels) @@ -214,7 +215,7 @@ /mob/living/simple_animal/parrot/attack_hand(mob/living/carbon/M as mob) ..() if(client) return - if(!stat && M.a_intent == "harm") + if(!stat && M.a_intent == "hurt") icon_state = "parrot_fly" //It is going to be flying regardless of whether it flees or attacks @@ -231,27 +232,8 @@ drop_held_item(0) return -/mob/living/simple_animal/parrot/attack_paw(mob/living/carbon/monkey/M as mob) - attack_hand(M) - -/mob/living/simple_animal/parrot/attack_alien(mob/living/carbon/monkey/M as mob) - attack_hand(M) - -//Simple animals -/mob/living/simple_animal/parrot/attack_animal(mob/living/simple_animal/M as mob) - if(client) return - - - if(parrot_state == PARROT_PERCH) - parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched - - if(M.melee_damage_upper > 0) - parrot_interest = M - parrot_state = PARROT_SWOOP | PARROT_ATTACK //Attack other animals regardless - icon_state = "parrot_fly" - //Mobs with objects -/mob/living/simple_animal/parrot/attackby(var/obj/item/O as obj, var/mob/user as mob) +/mob/living/simple_animal/parrot/attackby(var/obj/item/O as obj, var/mob/user as mob, params) ..() if(!stat && !client && !istype(O, /obj/item/stack/medical)) if(O.force) @@ -335,7 +317,7 @@ if(speak.len) var/list/newspeak = list() - if(available_channels.len && src.l_ear) + if(available_channels.len && src.ears) for(var/possible_phrase in speak) //50/50 chance to not use the radio at all @@ -496,11 +478,11 @@ var/datum/organ/external/affecting = H.get_organ(ran_zone(pick(parrot_dam_zone))) H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), sharp=1) - emote(pick("pecks [H]'s [affecting]", "cuts [H]'s [affecting] with its talons")) + emote(pick("pecks [H]'s [affecting].", "cuts [H]'s [affecting] with its talons.")) else L.adjustBruteLoss(damage) - emote(pick("pecks at [L]", "claws [L]")) + emote(pick("pecks at [L].", "claws [L].")) return //Otherwise, fly towards the mob! @@ -625,7 +607,7 @@ stolen_item = C.r_hand if(stolen_item) - C.u_equip(stolen_item) + C.unEquip(stolen_item) held_item = stolen_item stolen_item.loc = src visible_message("[src] grabs the [held_item] out of [C]'s hand!", "\blue You snag the [held_item] out of [C]'s hand!", "You hear the sounds of wings flapping furiously.") @@ -700,6 +682,71 @@ speak = list("Poly wanna cracker!", ":e Check the singlo, you chucklefucks!",":e Wire the solars, you lazy bums!",":e WHO TOOK THE DAMN HARDSUITS?",":e OH GOD ITS FREE CALL THE SHUTTLE") /mob/living/simple_animal/parrot/Poly/New() - l_ear = new /obj/item/device/radio/headset/headset_eng(src) + ears = new /obj/item/device/radio/headset/headset_eng(src) available_channels = list(":e") ..() + +/mob/living/simple_animal/parrot/say(var/message) + + if(stat) + return + + var/verb = "says" + if(speak_emote.len) + verb = pick(speak_emote) + + var/message_mode = null + if(copytext(message,1,2) == ";") + message_mode = "headset" + message = copytext(message,2) + + if(copytext(message,1,2) == ":") + var/channel_prefix = copytext(message, 1 ,3) + message_mode = department_radio_keys[channel_prefix] + var/positioncut = 3 + message = trim(copytext(message,positioncut)) + + message = capitalize(trim_left(message)) + if(message_mode) + if(message_mode in radiochannels) + if(ears && istype(ears,/obj/item/device/radio)) + ears.talk_into(src, message, message_mode, verb, null) + + ..(message) + + +/mob/living/simple_animal/parrot/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "",var/italics = 0, var/mob/speaker = null) + if(prob(50)) + parrot_hear(message) + ..(message,verb,language,alt_name,italics,speaker) + + + +/mob/living/simple_animal/parrot/hear_radio(var/message, var/verb="says", var/datum/language/language=null, var/part_a, var/part_b, var/mob/speaker = null, var/hard_to_hear = 0) + if(prob(50)) + parrot_hear("[pick(available_channels)] [message]") + ..(message,verb,language,part_a,part_b,speaker,hard_to_hear) + + +/mob/living/simple_animal/parrot/proc/parrot_hear(var/message="") + if(!message || stat) + return + speech_buffer.Add(message) + +/mob/living/simple_animal/parrot/attack_paw(var/mob/user, var/damage, var/attack_message) + + var/success = ..() + + if(client) + return success + + if(parrot_state == PARROT_PERCH) + parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched + + if(!success) + return 0 + + parrot_interest = user + parrot_state = PARROT_SWOOP | PARROT_ATTACK //Attack other animals regardless + icon_state = "parrot_fly" + return success diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 890c953c632..d8beb5aaca9 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -10,6 +10,10 @@ var/icon_dead = "" var/icon_gib = null //We only try to show a gibbing animation if this exists. + var/oxygen_alert = 0 + var/toxins_alert = 0 + var/fire_alert = 0 + var/list/speak = list() var/speak_chance = 0 var/list/emote_hear = list() //Hearable emotes @@ -29,6 +33,7 @@ var/response_disarm = "shoves" var/response_harm = "hits" var/harm_intent_damage = 3 + var/force_threshold = 0 //Minimum force required to deal any damage //Temperature effect var/minbodytemp = 250 @@ -104,7 +109,7 @@ handle_paralysed() //Movement - if(!client && !stop_automated_movement && wander) + if(!client && !stop_automated_movement && wander && (ckey == null)) if(isturf(src.loc) && !resting && !buckled && canmove) //This is so it only moves if it's not inside a closet, gentics machine, etc. turns_since_move++ if(turns_since_move >= turns_per_move) @@ -113,7 +118,7 @@ turns_since_move = 0 //Speaking - if(!client && speak_chance) + if(!client && speak_chance && (ckey == null)) if(rand(0,200) < speak_chance) if(speak && speak.len) if((emote_hear && emote_hear.len) || (emote_see && emote_see.len)) @@ -165,6 +170,9 @@ if(min_oxy) if(Environment.oxygen < min_oxy) atmos_suitable = 0 + oxygen_alert = 1 + else + oxygen_alert = 0 if(max_oxy) if(Environment.oxygen > max_oxy) atmos_suitable = 0 @@ -174,6 +182,9 @@ if(max_tox) if(Environment.toxins > max_tox) atmos_suitable = 0 + toxins_alert = 1 + else + toxins_alert = 0 if(min_n2) if(Environment.nitrogen < min_n2) atmos_suitable = 0 @@ -191,9 +202,13 @@ //Atmos effect if(bodytemperature < minbodytemp) + fire_alert = 2 adjustBruteLoss(cold_damage_per_tick) else if(bodytemperature > maxbodytemp) + fire_alert = 1 adjustBruteLoss(heat_damage_per_tick) + else + fire_alert = 0 if(!atmos_suitable) adjustBruteLoss(unsuitable_atoms_damage) @@ -235,18 +250,16 @@ m_type = 2 ..() - - /mob/living/simple_animal/attack_animal(mob/living/simple_animal/M as mob) if(M.melee_damage_upper == 0) - M.emote("[M.friendly] [src]") + M.emote("me", 1, "[M.friendly] [src]") else + M.do_attack_animation(src) if(M.attack_sound) playsound(loc, M.attack_sound, 50, 1, 1) - for(var/mob/O in viewers(src, null)) - O.show_message("\red \The [M] [M.attacktext] [src]!", 1) - M.attack_log += text("\[[time_stamp()]\] attacked [src.name] ([src.ckey])") - src.attack_log += text("\[[time_stamp()]\] was attacked by [M.name] ([M.ckey])") + visible_message("\The [M] [M.attacktext] [src]!", \ + "\The [M] [M.attacktext] [src]!") + add_logs(M, src, "attacked", admin=0) var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) adjustBruteLoss(damage) @@ -265,9 +278,8 @@ if("help") if (health > 0) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message("\blue [M] [response_help] [src].") + visible_message(" [M] [response_help] [src].") + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) if("grab") if (M == src || anchored) @@ -279,32 +291,51 @@ M.put_in_active_hand(G) - grabbed_by += G G.synch() LAssailant = M - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has grabbed [] passively!", M, src), 1) + visible_message("[M] has grabbed [src] passively!") + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) if("harm", "disarm") + M.do_attack_animation(src) + visible_message("[M] [response_harm] [src]!") + playsound(loc, "punch", 25, 1, -1) adjustBruteLoss(harm_intent_damage) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message("\red [M] [response_harm] [src]!") return +/mob/living/simple_animal/attack_paw(mob/living/carbon/monkey/M as mob) + if(!(istype(M, /mob/living/carbon/monkey))) + return // Fix for aliens receiving double messages when attacking simple animals. + + ..() + + switch(M.a_intent) + + if ("help") + if (health > 0) + visible_message(" [M] [response_help] [src].") + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + else + M.do_attack_animation(src) + if (istype(src.wear_mask, /obj/item/clothing/mask/muzzle)) + return + playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) + visible_message("[M.name] bites [src]!", \ + "[M.name] bites [src]!") + if (health > -100) + adjustBruteLoss(rand(1, 3)) + return + /mob/living/simple_animal/attack_alien(mob/living/carbon/alien/humanoid/M as mob) switch(M.a_intent) if ("help") - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\blue [M] caresses [src] with its scythe like arm."), 1) + visible_message("[M] caresses [src] with its scythe like arm.") if ("grab") if(M == src || anchored) return @@ -315,18 +346,18 @@ M.put_in_active_hand(G) - grabbed_by += G G.synch() LAssailant = M playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has grabbed [] passively!", M, src), 1) + visible_message("[M] has grabbed [src] passively!") - else + if("harm", "disarm") + M.do_attack_animation(src) var/damage = rand(15, 30) - visible_message("\red [M] has slashed at [src]!") + visible_message("[M] has slashed at [src]!", \ + "[M] has slashed at [src]!") + playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1) adjustBruteLoss(damage) return @@ -335,17 +366,19 @@ switch(L.a_intent) if("help") - visible_message("\blue [L] rubs it's head against [src]") + visible_message("[L] rubs its head against [src].") else - + L.do_attack_animation(src) var/damage = rand(5, 10) - visible_message("\red [L] bites [src]!") + visible_message("[L] bites [src]!", \ + "[L] bites [src]!") + playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) if(stat != DEAD) - adjustBruteLoss(damage) L.amount_grown = min(L.amount_grown + damage, L.max_grown) + adjustBruteLoss(damage) /mob/living/simple_animal/attack_slime(mob/living/carbon/slime/M as mob) @@ -355,24 +388,25 @@ if(M.Victim) return // can't attack while eating! - visible_message("\red [M.name] glomps [src]!") + if (health > 0) + M.do_attack_animation(src) + visible_message("[M.name] glomps [src]!", \ + "[M.name] glomps [src]!") - var/damage = rand(1, 3) + var/damage = rand(1, 3) - if(M.is_adult) - damage = rand(20, 40) - else - damage = rand(5, 35) + if(M.is_adult) + damage = rand(20, 40) + else + damage = rand(5, 35) - adjustBruteLoss(damage) + adjustBruteLoss(damage) return - -/mob/living/simple_animal/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri +/mob/living/simple_animal/attackby(var/obj/item/O as obj, var/mob/living/user as mob) //Marker -Agouri if(istype(O, /obj/item/stack/medical)) - if(stat != DEAD) var/obj/item/stack/medical/MED = O if(health < maxHealth) @@ -399,20 +433,24 @@ if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch)) harvest() else + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) + var/damage = 0 if(O.force) - var/damage = O.force - if (O.damtype == STAMINA) - damage = 0 - adjustBruteLoss(damage) - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red \b "+"[src] has been attacked with [O] by [user]. ") + if(O.force >= force_threshold) + damage = O.force + if (O.damtype == STAMINA) + damage = 0 + visible_message("[user] has [O.attack_verb.len ? "[pick(O.attack_verb)]": "attacked"] [src] with [O]!",\ + "[user] has [O.attack_verb.len ? "[pick(O.attack_verb)]": "attacked"] you with [O]!") + else + visible_message("[O] bounces harmlessly off of [src].",\ + "[O] bounces harmlessly off of [src].") + playsound(loc, O.hitsound, 50, 1, -1) else - usr << "\red This weapon is ineffective, it does no damage." - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red [user] gently taps [src] with [O]. ") - + user.visible_message("[user] gently taps [src] with [O].",\ + "This weapon is ineffective, it does no damage.") + adjustBruteLoss(damage) /mob/living/simple_animal/movement_delay() @@ -535,3 +573,22 @@ if (S.occupant || S.occupant2) return 0 return 1 + +/mob/living/simple_animal/say(var/message) + if(stat) + return + + if(copytext(message,1,2) == "*") + return emote(copytext(message,2)) + + if(stat) + return + + var/verb = "says" + + if(speak_emote.len) + verb = pick(speak_emote) + + message = capitalize(trim_left(message)) + + ..(message, null, verb) diff --git a/code/modules/mob/living/simple_animal/tribbles.dm b/code/modules/mob/living/simple_animal/tribbles.dm index 649b27f334b..77a23ab6fe0 100644 --- a/code/modules/mob/living/simple_animal/tribbles.dm +++ b/code/modules/mob/living/simple_animal/tribbles.dm @@ -51,7 +51,7 @@ var/global/totaltribbles = 0 //global variable so it updates for all tribbles, del(src) -/mob/living/simple_animal/tribble/attackby(var/obj/item/weapon/O as obj, var/mob/user as mob) +/mob/living/simple_animal/tribble/attackby(var/obj/item/weapon/O as obj, var/mob/user as mob, params) if(istype(O, /obj/item/weapon/scalpel)) user << "You try to neuter the tribble, but it's moving too much and you fail!" else if(istype(O, /obj/item/weapon/cautery)) @@ -190,7 +190,7 @@ var/global/totaltribbles = 0 //global variable so it updates for all tribbles, return -/obj/structure/tribble_cage/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/tribble_cage/attackby(obj/item/weapon/W as obj, mob/user as mob, params) src.health -= W.force src.healthcheck() ..() diff --git a/code/modules/mob/living/simple_animal/vox.dm b/code/modules/mob/living/simple_animal/vox.dm index 02e8a3e9460..d350e7c4704 100644 --- a/code/modules/mob/living/simple_animal/vox.dm +++ b/code/modules/mob/living/simple_animal/vox.dm @@ -32,7 +32,7 @@ src.gib() return -/mob/living/simple_animal/vox/armalis/attackby(var/obj/item/O as obj, var/mob/user as mob) +/mob/living/simple_animal/vox/armalis/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(O.force) if(O.force >= 25) var/damage = O.force @@ -110,7 +110,7 @@ set name = "Shriek" set desc = "Give voice to a psychic shriek." -/mob/living/simple_animal/vox/armalis/attackby(var/obj/item/O as obj, var/mob/user as mob) +/mob/living/simple_animal/vox/armalis/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(istype(O,/obj/item/vox/armalis_armour)) user.drop_item() armour = O diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index 27127a83e4e..39a1fb53631 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -57,18 +57,20 @@ client.verbs |= H.species.abilities CallHook("Login", list("client" = src.client, "mob" = src)) - + //Update morgues on login/logout if (stat == DEAD) var/obj/structure/morgue/Morgue = null var/mob/living/carbon/human/C = null if (istype(src,/mob/dead/observer)) //We're a ghost, let's find our corpse var/mob/dead/observer/G = src + if(!G.mind) //This'll probably break morgue sprites, but the line under the next If statement causes runtimes with Assume Direct Control. + return if (G.can_reenter_corpse && G.mind.current) C = G.mind.current else if (istype(src,/mob/living/carbon/human)) C = src - + if (C) //We found our corpse, is it inside a morgue? if (istype(C.loc,/obj/structure/morgue)) Morgue = C.loc @@ -78,4 +80,4 @@ Morgue = B.loc if (Morgue) Morgue.update() - + diff --git a/code/modules/mob/logout.dm b/code/modules/mob/logout.dm index 45449c1e1c7..36df2619e38 100644 --- a/code/modules/mob/logout.dm +++ b/code/modules/mob/logout.dm @@ -10,18 +10,20 @@ if(admins_number == 0) //Apparently the admin logging out is no longer an admin at this point, so we have to check this towards 0 and not towards 1. Awell. send2adminirc("[key_name(src)] logged out - no more admins online.") ..() - + //Update morgues on login/logout if (stat == DEAD) var/obj/structure/morgue/Morgue = null var/mob/living/carbon/human/C = null if (istype(src,/mob/dead/observer)) //We're a ghost, let's find our corpse var/mob/dead/observer/G = src + if(!G.mind) //This'll probably break morgue sprites, but the line under the next If statement causes runtimes with Assume Direct Control. + return 1 if (G.can_reenter_corpse && G.mind.current) C = G.mind.current else if (istype(src,/mob/living/carbon/human)) C = src - + if (C) //We found our corpse, is it inside a morgue? if (istype(C.loc,/obj/structure/morgue)) Morgue = C.loc diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 6abce2c37d7..9f54d762431 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -93,6 +93,7 @@ return 0 /mob/proc/Life() +// handle_typing_indicator() // if(organStructure) // organStructure.ProcessOrgans() return @@ -193,6 +194,7 @@ var/list/slot_equipment_priority = list( \ slot_glasses,\ slot_belt,\ slot_s_store,\ + slot_tie,\ slot_l_store,\ slot_r_store\ ) @@ -245,7 +247,7 @@ var/list/slot_equipment_priority = list( \ if( !(slot_flags & SLOT_BACK) ) return 0 if(H.back) - if(H.back.canremove) + if(!(H.back.flags & NODROP)) return 2 else return 0 @@ -254,7 +256,7 @@ var/list/slot_equipment_priority = list( \ if( !(slot_flags & SLOT_OCLOTHING) ) return 0 if(H.wear_suit) - if(H.wear_suit.canremove) + if(!(H.wear_suit.flags & NODROP)) return 2 else return 0 @@ -263,7 +265,7 @@ var/list/slot_equipment_priority = list( \ if( !(slot_flags & SLOT_GLOVES) ) return 0 if(H.gloves) - if(H.gloves.canremove) + if(!(H.gloves.flags & NODROP)) return 2 else return 0 @@ -272,7 +274,7 @@ var/list/slot_equipment_priority = list( \ if( !(slot_flags & SLOT_FEET) ) return 0 if(H.shoes) - if(H.shoes.canremove) + if(!(H.shoes.flags & NODROP)) return 2 else return 0 @@ -285,7 +287,7 @@ var/list/slot_equipment_priority = list( \ if( !(slot_flags & SLOT_BELT) ) return 0 if(H.belt) - if(H.belt.canremove) + if(!(H.belt.flags & NODROP)) return 2 else return 0 @@ -294,7 +296,7 @@ var/list/slot_equipment_priority = list( \ if( !(slot_flags & SLOT_EYES) ) return 0 if(H.glasses) - if(H.glasses.canremove) + if(!(H.glasses.flags & NODROP)) return 2 else return 0 @@ -303,7 +305,7 @@ var/list/slot_equipment_priority = list( \ if( !(slot_flags & SLOT_HEAD) ) return 0 if(H.head) - if(H.head.canremove) + if(!(H.head.flags & NODROP)) return 2 else return 0 @@ -312,7 +314,7 @@ var/list/slot_equipment_priority = list( \ if( !(slot_flags & slot_l_ear) ) return 0 if(H.l_ear) - if(H.l_ear.canremove) + if(!(H.l_ear.flags & NODROP)) return 2 else return 0 @@ -321,7 +323,7 @@ var/list/slot_equipment_priority = list( \ if( !(slot_flags & slot_r_ear) ) return 0 if(H.r_ear) - if(H.r_ear.canremove) + if(!(H.r_ear.flags & NODROP)) return 2 else return 0 @@ -329,10 +331,10 @@ var/list/slot_equipment_priority = list( \ if(slot_w_uniform) if( !(slot_flags & SLOT_ICLOTHING) ) return 0 - if((M_FAT in H.mutations) && !(flags & ONESIZEFITSALL)) + if((FAT in H.mutations) && !(flags & ONESIZEFITSALL)) return 0 if(H.w_uniform) - if(H.w_uniform.canremove) + if(!(H.w_uniform.flags & NODROP)) return 2 else return 0 @@ -345,7 +347,7 @@ var/list/slot_equipment_priority = list( \ if( !(slot_flags & SLOT_ID) ) return 0 if(H.wear_id) - if(H.wear_id.canremove) + if(!(H.wear_id.flags & NODROP)) return 2 else return 0 @@ -388,7 +390,7 @@ var/list/slot_equipment_priority = list( \ return 0 if( istype(src, /obj/item/device/pda) || istype(src, /obj/item/weapon/pen) || is_type_in_list(src, H.wear_suit.allowed) ) if(H.s_store) - if(H.s_store.canremove) + if(!(H.s_store.flags & NODROP)) return 2 else return 0 @@ -398,13 +400,13 @@ var/list/slot_equipment_priority = list( \ if(slot_handcuffed) if(H.handcuffed) return 0 - if(!istype(src, /obj/item/weapon/handcuffs)) + if(!istype(src, /obj/item/weapon/restraints/handcuffs)) return 0 return 1 if(slot_legcuffed) if(H.legcuffed) return 0 - if(!istype(src, /obj/item/weapon/legcuffs)) + if(!istype(src, /obj/item/weapon/restraints/legcuffs)) return 0 return 1 if(slot_in_backpack) @@ -437,9 +439,9 @@ var/list/slot_equipment_priority = list( \


[name]


Head(Mask): [(wear_mask ? wear_mask : "Nothing")] -
Left Hand: [(l_hand ? l_hand : "Nothing")] -
Right Hand: [(r_hand ? r_hand : "Nothing")] -
Back: [(back ? back : "Nothing")] [((istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank) && !( internal )) ? text(" Set Internal", src) : "")] +
Left Hand: [(l_hand && !(l_hand.flags & ABSTRACT)) ? l_hand : "Nothing"] +
Right Hand: [(r_hand && !(r_hand.flags & ABSTRACT)) ? r_hand : "Nothing"] +
Back: [(back && !(back.flags & ABSTRACT)) ? back : "Nothing"] [((istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank) && !( internal )) ? text(" Set Internal", src) : "")]
[(internal ? text("Remove Internal") : "")]
Empty Pockets
Refresh @@ -501,8 +503,6 @@ var/list/slot_equipment_priority = list( \ if (W) W.attack_self(src) update_inv_r_hand() - if(next_move < world.time) - next_move = world.time + 2 return /* @@ -757,12 +757,13 @@ var/list/slot_equipment_priority = list( \ /mob/proc/pull_damage() if(ishuman(src)) var/mob/living/carbon/human/H = src - if(H.health - H.halloss <= config.health_threshold_crit) + if(H.health - H.halloss <= config.health_threshold_softcrit) for(var/name in H.organs_by_name) var/datum/organ/external/e = H.organs_by_name[name] - if((H.lying) && ((e.status & ORGAN_BROKEN && !(e.status & ORGAN_SPLINTED)) || e.status & ORGAN_BLEEDING) && (H.getBruteLoss() + H.getFireLoss() >= 100)) - return 1 - break + if(H.lying) + if(((e.status & ORGAN_BROKEN && !(e.status & ORGAN_SPLINTED)) || e.status & ORGAN_BLEEDING) && (H.getBruteLoss() + H.getFireLoss() >= 100)) + return 1 + break return 0 /mob/MouseDrop(mob/M as mob) @@ -856,6 +857,9 @@ var/list/slot_equipment_priority = list( \ src << message return 1 +/mob/proc/is_muzzled() + return 0 + /mob/proc/show_viewers(message) for(var/mob/M in viewers()) M.see(message) @@ -870,23 +874,76 @@ var/list/slot_equipment_priority = list( \ stat(null, "CPU:\t[world.cpu]") stat(null, "Instances:\t[world.contents.len]") - if(master_controller) - stat(null, "MasterController-[last_tick_duration] ([master_controller.processing?"On":"Off"]-[controller_iteration])") - stat(null, "Air-[master_controller.air_cost]") - stat(null, "Sun-[master_controller.sun_cost]") - stat(null, "Mob-[master_controller.mobs_cost]\t#[mob_list.len]") - stat(null, "Dis-[master_controller.diseases_cost]\t#[active_diseases.len]") - stat(null, "Mch-[master_controller.machines_cost]\t#[machines.len]") - stat(null, "Bots-[master_controller.aibots_cost]\t#[aibots.len]") - stat(null, "Obj-[master_controller.objects_cost]\t#[processing_objects.len]") - stat(null, "PiNet-[master_controller.networks_cost]\t#[pipe_networks.len]") - stat(null, "Ponet-[master_controller.powernets_cost]\t#[powernets.len]") - stat(null, "NanoUI-[master_controller.nano_cost]\t#[nanomanager.processing_uis.len]") -// stat(null, "GC-[master_controller.gc_cost]\t#[garbage.queue.len]") - stat(null, "Tick-[master_controller.ticker_cost]") - stat(null, "ALL-[master_controller.total_cost]") + if (garbageCollector) + stat(null, "\tqdel - [garbageCollector.del_everything ? "off" : "on"]") + stat(null, "\ton queue - [garbageCollector.queue.len]") + stat(null, "\ttotal delete - [garbageCollector.dels_count]") + stat(null, "\tsoft delete - [garbageCollector.soft_dels]") + stat(null, "\thard delete - [garbageCollector.hard_dels]") else - stat(null, "MasterController-ERROR") + stat(null, "Garbage Controller is not running.") + + if(processScheduler.getIsRunning()) + var/datum/controller/process/process + + process = processScheduler.getProcess("ticker") + stat(null, "TIC\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + process = processScheduler.getProcess("air") + stat(null, "AIR\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + process = processScheduler.getProcess("lighting") + stat(null, "LIG\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + process = processScheduler.getProcess("mob") + stat(null, "MOB([mob_list.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + process = processScheduler.getProcess("machinery") + stat(null, "MAC([machines.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + process = processScheduler.getProcess("obj") + stat(null, "OBJ([processing_objects.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + process = processScheduler.getProcess("bot") + stat(null, "BOT([aibots.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + process = processScheduler.getProcess("pipenet") + stat(null, "PIP([pipe_networks.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + process = processScheduler.getProcess("powernet") + stat(null, "POW([powernets.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + process = processScheduler.getProcess("nanoui") + stat(null, "NAN([nanomanager.processing_uis.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + process = processScheduler.getProcess("disease") + stat(null, "DIS([active_diseases.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + process = processScheduler.getProcess("garbage") + stat(null, "GAR\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + //process = processScheduler.getProcess("sun") + //stat(null, "SUN\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + //process = processScheduler.getProcess("garbage") + //stat(null, "GAR\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + //process = processScheduler.getProcess("vote") + //stat(null, "VOT\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + //process = processScheduler.getProcess("shuttle controller") + //stat(null, "SHT\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + //process = processScheduler.getProcess("emergency shuttle") + //stat(null, "EME\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + //process = processScheduler.getProcess("inactivity") + //stat(null, "IAC\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + //process = processScheduler.getProcess("event") + //stat(null, "EVE([events.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + else + stat(null, "processScheduler is not running.") if(listed_turf && client) if(!TurfAdjacent(listed_turf)) @@ -896,8 +953,13 @@ var/list/slot_equipment_priority = list( \ for(var/atom/A in listed_turf) if(A.invisibility > see_invisible) continue + if(is_type_in_list(A, shouldnt_see)) + continue statpanel(listed_turf.name, null, A) + if(mind && mind.changeling) + add_stings_to_statpanel(mind.changeling.purchasedpowers) + if(spell_list && spell_list.len) for(var/obj/effect/proc_holder/spell/wizard/S in spell_list) switch(S.charge_type) @@ -908,6 +970,11 @@ var/list/slot_equipment_priority = list( \ if("holdervar") statpanel(S.panel,"[S.holder_var_type] [S.holder_var_amount]",S) + +/mob/proc/add_stings_to_statpanel(var/list/stings) + for(var/obj/effect/proc_holder/changeling/S in stings) + if(S.chemical_cost >=0 && S.can_be_used_by(src)) + statpanel("[S.panel]",((S.chemical_cost > 0) ? "[S.chemical_cost]" : ""),S) /* // Why have a duplicate set of turfs in the stat panel? if(listed_turf) if(get_dist(listed_turf,src) > 1) @@ -1050,16 +1117,19 @@ var/list/slot_equipment_priority = list( \ /mob/proc/Stun(amount) if(status_flags & CANSTUN) stunned = max(max(stunned,amount),0) //can't go below 0, getting a low amount of stun doesn't lower your current stun + update_canmove() return /mob/proc/SetStunned(amount) //if you REALLY need to set stun to a set amount without the whole "can't go below current stunned" if(status_flags & CANSTUN) stunned = max(amount,0) + update_canmove() return /mob/proc/AdjustStunned(amount) if(status_flags & CANSTUN) stunned = max(stunned + amount,0) + update_canmove() return /mob/proc/Weaken(amount) @@ -1083,40 +1153,49 @@ var/list/slot_equipment_priority = list( \ /mob/proc/Paralyse(amount) if(status_flags & CANPARALYSE) paralysis = max(max(paralysis,amount),0) + update_canmove() return /mob/proc/SetParalysis(amount) if(status_flags & CANPARALYSE) paralysis = max(amount,0) + update_canmove() return /mob/proc/AdjustParalysis(amount) if(status_flags & CANPARALYSE) paralysis = max(paralysis + amount,0) + update_canmove() return /mob/proc/Sleeping(amount) sleeping = max(max(sleeping,amount),0) + update_canmove() return /mob/proc/SetSleeping(amount) sleeping = max(amount,0) + update_canmove() return /mob/proc/AdjustSleeping(amount) sleeping = max(sleeping + amount,0) + update_canmove() return /mob/proc/Resting(amount) resting = max(max(resting,amount),0) + update_canmove() return /mob/proc/SetResting(amount) resting = max(amount,0) + update_canmove() return /mob/proc/AdjustResting(amount) resting = max(resting + amount,0) + update_canmove() return /mob/proc/get_species() @@ -1140,7 +1219,7 @@ mob/proc/yank_out_object() if(!isliving(usr) || usr.next_move > world.time) return - usr.next_move = world.time + 20 + usr.changeNext_move(CLICK_CD_RESIST) if(usr.stat == 1) usr << "You are unconcious and cannot do that!" @@ -1226,7 +1305,7 @@ mob/proc/yank_out_object() if(jobban_isbanned(usr, "NPC")) usr << "You are banned from playing as NPC's." return - + if((usr in respawnable_list) && (stat==2 || istype(usr,/mob/dead/observer))) var/list/creatures = list("Mouse") for(var/mob/living/L in living_mob_list) @@ -1331,4 +1410,4 @@ mob/proc/yank_out_object() if(G.mind == mind) if(G.can_reenter_corpse || even_if_they_cant_reenter) return G - break \ No newline at end of file + break diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index b91583758af..d508eb7fb92 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -138,6 +138,8 @@ var/coughedtime = null + var/emote_cd = 0 // Used to supress emote spamming. 1 if on CD, 2 if disabled by admin (manually set), else 0 + var/inertia_dir = 0 var/music_lastplayed = "null" @@ -220,6 +222,7 @@ var/immune_to_ssd = 0 var/turf/listed_turf = null //the current turf being examined in the stat panel + var/list/shouldnt_see = list() //list of objects that this mob shouldn't see in the stat panel. this silliness is needed because of AI alt+click and cult blood runes var/kills=0 diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index 29bc7aed076..01f32df8e14 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -3,7 +3,7 @@ /obj/item/weapon/grab name = "grab" - flags = NOBLUDGEON + flags = NOBLUDGEON | ABSTRACT var/obj/screen/grab/hud = null var/mob/affecting = null var/mob/assailant = null @@ -12,7 +12,6 @@ var/last_upgrade = 0 layer = 21 - abstract = 1 item_state = "nothing" w_class = 5.0 @@ -161,7 +160,7 @@ affecting.LAssailant = null else affecting.LAssailant = assailant - assailant.next_move = world.time + 10 + assailant.changeNext_move(CLICK_CD_TKSTRANGLE) affecting.losebreath += 1 else assailant.visible_message("[assailant] was unable to tighten \his grip on [affecting]'s neck!") @@ -190,7 +189,7 @@ s_click(hud) return if(M == assailant && state >= GRAB_AGGRESSIVE) - if( (ishuman(user) && (M_FAT in user.mutations) && iscarbon(affecting) ) || ( isalien(user) && iscarbon(affecting) ) || ( istype(user,/mob/living/carbon/human/kidan) && istype(affecting,/mob/living/carbon/monkey/diona) ) ) + if( (ishuman(user) && (FAT in user.mutations) && iscarbon(affecting) ) || ( isalien(user) && iscarbon(affecting) ) || ( istype(user,/mob/living/carbon/human/kidan) && istype(affecting,/mob/living/carbon/monkey/diona) ) ) var/mob/living/carbon/attacker = user user.visible_message("[user] is attempting to devour [affecting]!") if(istype(user, /mob/living/carbon/alien/humanoid/hunter)) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 0432e4baef6..d306f739835 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -114,6 +114,11 @@ proc/isembryo(A) if(istype(A, /mob/living/silicon)) return 1 return 0 + +/proc/isSilicon(A) // Bay support + if(istype(A, /mob/living/silicon)) + return 1 + return 0 /proc/isliving(A) if(istype(A, /mob/living)) @@ -150,7 +155,7 @@ proc/isorgan(A) if(L && L.implanted) return 1 return 0 - + proc/isnewplayer(A) if(istype(A, /mob/new_player)) return 1 @@ -158,10 +163,31 @@ proc/isnewplayer(A) proc/hasorgans(A) return ishuman(A) + +proc/iscuffed(A) + if(istype(A, /mob/living/carbon)) + var/mob/living/carbon/C = A + if(C.handcuffed) + return 1 + return 0 + +proc/isdeaf(A) + if(istype(A, /mob)) + var/mob/M = A + return (M.sdisabilities & DEAF) || M.ear_deaf + return 0 /proc/hsl2rgb(h, s, l) return +proc/hassensorlevel(A, var/level) + var/mob/living/carbon/human/H = A + if(istype(H) && istype(H.w_uniform, /obj/item/clothing/under)) + var/obj/item/clothing/under/U = H.w_uniform + return U.sensor_mode >= level + return 0 + + /proc/check_zone(zone) if(!zone) return "chest" @@ -199,6 +225,13 @@ proc/hasorgans(A) return zone +/proc/above_neck(zone) + var/list/zones = list("head", "mouth", "eyes") + if(zones.Find(zone)) + return 1 + else + return 0 + /proc/stars(n, pr) if (pr == null) pr = 25 @@ -264,7 +297,7 @@ proc/slur(phrase) n_letter = text("[n_letter]-[n_letter]") t = text("[t][n_letter]")//since the above is ran through for each letter, the text just adds up back to the original word. p++//for each letter p is increased to find where the next letter will be. - return copytext(sanitize(t),1,MAX_MESSAGE_LEN) + return sanitize(copytext(t,1,MAX_MESSAGE_LEN)) proc/Gibberish(t, p)//t is the inputted message, and any value higher than 70 for p will cause letters to be replaced instead of added @@ -311,7 +344,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp n_letter = text("[n_letter]") t = text("[t][n_letter]") p=p+n_mod - return copytext(sanitize(t),1,MAX_MESSAGE_LEN) + return sanitize(copytext(t,1,MAX_MESSAGE_LEN)) /proc/shake_camera(mob/M, duration, strength=1) @@ -344,10 +377,10 @@ It's fairly easy to fix if dealing with single letters but not so much with comp /mob/proc/abiotic(var/full_body = 0) - if(full_body && ((src.l_hand && !( src.l_hand.abstract )) || (src.r_hand && !( src.r_hand.abstract )) || (src.back || src.wear_mask))) + if(full_body && ((src.l_hand && !(src.l_hand.flags & ABSTRACT)) || (src.r_hand && !(src.r_hand.flags & ABSTRACT)) || (src.back || src.wear_mask))) return 1 - if((src.l_hand && !( src.l_hand.abstract )) || (src.r_hand && !( src.r_hand.abstract ))) + if((src.l_hand && !(src.l_hand.flags & ABSTRACT)) || (src.r_hand && !(src.r_hand.flags & ABSTRACT))) return 1 return 0 @@ -432,3 +465,49 @@ var/list/intents = list("help","disarm","grab","harm") /proc/get_both_hands(mob/living/carbon/M) var/list/hands = list(M.l_hand, M.r_hand) return hands + + +//Direct dead say used both by emote and say +//It is somewhat messy. I don't know what to do. +//I know you can't see the change, but I rewrote the name code. It is significantly less messy now +/proc/say_dead_direct(var/message, var/mob/subject = null) + var/name + var/keyname + if(subject && subject.client) + var/client/C = subject.client + keyname = (C.holder && C.holder.fakekey) ? C.holder.fakekey : C.key + if(C.mob) //Most of the time this is the dead/observer mob; we can totally use him if there is no better name + var/mindname + var/realname = C.mob.real_name + if(C.mob.mind) + mindname = C.mob.mind.name + if(C.mob.mind.original && C.mob.mind.original.real_name) + realname = C.mob.mind.original.real_name + if(mindname && mindname != realname) + name = "[realname] died as [mindname]" + else + name = realname + + for(var/mob/M in player_list) + if(M.client && ((!istype(M, /mob/new_player) && M.stat == DEAD) || (M.client.holder && (M.client.holder.rights & R_MOD))) && (M.client.prefs.toggles & CHAT_DEAD)) + var/follow + var/lname + if(subject) + if(subject != M) + follow = "(follow) " + if(M.stat != DEAD && M.client.holder) + follow = "(JMP) " + var/mob/dead/observer/DM + if(istype(subject, /mob/dead/observer)) + DM = subject + if(M.client.holder) // What admins see + lname = "[keyname][(DM && DM.anonsay) ? "*" : (DM ? "" : "^")] ([name])" + else + if(DM && DM.anonsay) // If the person is actually observer they have the option to be anonymous + lname = "Ghost of [name]" + else if(DM) // Non-anons + lname = "[keyname] ([name])" + else // Everyone else (dead people who didn't ghost yet, etc.) + lname = name + lname = "[lname] " + M << "[lname][follow][message]" diff --git a/code/modules/mob/mob_transformation_simple.dm b/code/modules/mob/mob_transformation_simple.dm index bea08693fbc..33428a9c096 100644 --- a/code/modules/mob/mob_transformation_simple.dm +++ b/code/modules/mob/mob_transformation_simple.dm @@ -2,7 +2,7 @@ //This proc is the most basic of the procs. All it does is make a new mob on the same tile and transfer over a few variables. //Returns the new mob //Note that this proc does NOT do MMI related stuff! -/mob/proc/change_mob_type(var/new_type = null, var/turf/location = null, var/new_name = null as text, var/delete_old_mob = 0 as num) +/mob/proc/change_mob_type(var/new_type = null, var/turf/location = null, var/new_name = null as text, var/delete_old_mob = 0 as num, var/forcekey = 0) if(istype(src,/mob/new_player)) usr << "\red cannot convert players who have not entered yet." @@ -30,7 +30,7 @@ if(!M || !ismob(M)) usr << "Type path is not a mob (new_type = [new_type]) in change_mob_type(). Contact a coder." - del(M) + qdel(M) return if( istext(new_name) ) @@ -43,12 +43,12 @@ if(src.dna) M.dna = src.dna.Clone() - if(mind) + if((mind && istype(M, /mob/living)) && !forcekey) mind.transfer_to(M) else M.key = key if(delete_old_mob) spawn(1) - del(src) + qdel(src) return M diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 6ecdfdc4e67..471aed1d7f2 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -24,9 +24,7 @@ proc/new_player_panel_proc() - var/output = "
New Player Options" - output +="
" - output += "

Setup Character

" + var/output = "

Setup Character

" if(!ticker || ticker.current_state <= GAME_STATE_PREGAME) if(!ready) output += "

Declare Ready

" @@ -57,9 +55,9 @@ else output += "

Show Player Polls

" - output += "
" + output += "" - var/datum/browser/popup = new(src, "playersetup", "
New Player Options
", 210, 240) + var/datum/browser/popup = new(src, "playersetup", "
New Player Options
", 220, 290) popup.set_window_options("can_close=0") popup.set_content(output) popup.open(0) @@ -105,6 +103,7 @@ if(href_list["ready"]) ready = !ready + new_player_panel_proc() if(href_list["refresh"]) src << browse(null, "window=playersetup") //closes the player setup window @@ -115,7 +114,7 @@ if(alert(src,"Are you sure you wish to observe? You will have to wait 30 minutes before being able to respawn!","Player Setup","Yes","No") == "Yes") if(!client) return 1 var/mob/dead/observer/observer = new() - + src << browse(null, "window=playersetup") spawning = 1 src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // MAD JAMS cant last forever yo @@ -309,7 +308,7 @@ EquipRacialItems(character) character = job_master.EquipRank(character, rank, 1) //equips the human EquipCustomItems(character) - + // AIs don't need a spawnpoint, they must spawn at an empty core if(character.mind.assigned_role == "AI") @@ -346,7 +345,7 @@ else character.loc = pick(latejoin) join_message = "has arrived on the station" - + character.lastarea = get_area(loc) // Moving wheelchair if they have one if(character.buckled && istype(character.buckled, /obj/structure/stool/bed/chair/wheelchair)) @@ -398,12 +397,12 @@ if(character.mind) if((character.mind.special_role != "MODE")) var/arrivalmessage = "A new[rank ? " [rank]" : " visitor" ] [join_message ? join_message : "has arrived on the station"]." - announcer.say(";[arrivalmessage]") + announcer.say(";[arrivalmessage]") else if(character.mind) if((character.mind.special_role != "MODE")) // can't use their name here, since cyborg namepicking is done post-spawn, so we'll just say "A new Cyborg has arrived"/"A new Android has arrived"/etc. - global_announcer.autosay("A new[rank ? " [rank]" : " visitor" ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer") + global_announcer.autosay("A new[rank ? " [rank]" : " visitor" ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer") proc/LateChoices() var/mills = world.time // 1/10 of a second, not real milliseconds but whatever @@ -444,45 +443,21 @@ proc/create_character() spawning = 1 close_spawn_windows() + var/mob/living/carbon/human/new_character + var/datum/species/chosen_species if(client.prefs.species) chosen_species = all_species[client.prefs.species] if(chosen_species) // Have to recheck admin due to no usr at roundstart. Latejoins are fine though. if(is_species_whitelisted(chosen_species) || has_admin_rights()) - switch(chosen_species.name) - if("Slime People") - new_character = new /mob/living/carbon/human/slime(loc) - if("Tajaran") - new_character = new /mob/living/carbon/human/tajaran(loc) - if("Unathi") - new_character = new /mob/living/carbon/human/unathi(loc) - if("Skrell") - new_character = new /mob/living/carbon/human/skrell(loc) - if("Diona") - new_character = new /mob/living/carbon/human/diona(loc) - if("Vox") - new_character = new /mob/living/carbon/human/vox(loc) - if("Vox Armalis") - new_character = new /mob/living/carbon/human/voxarmalis(loc) - if("Kidan") - new_character = new /mob/living/carbon/human/kidan(loc) - if("Grey") - new_character = new /mob/living/carbon/human/grey(loc) - if("Machine") - new_character = new /mob/living/carbon/human/machine(loc) - if("Plasmaman") - new_character = new /mob/living/carbon/human/plasma(loc) - if("Human") - new_character = new /mob/living/carbon/human/human(loc) -// new_character.set_species(client.prefs.species) - if(chosen_species.language) - new_character.add_language(chosen_species.language) - else - new_character = new /mob/living/carbon/human(loc) - new_character.lastarea = get_area(loc) + new_character = new(loc, client.prefs.species) + if(!new_character) + new_character = new(loc) + + new_character.lastarea = get_area(loc) var/datum/language/chosen_language if(client.prefs.language) @@ -519,7 +494,7 @@ new_character.disabilities |= NEARSIGHTED if(client.prefs.disabilities & DISABILITY_FLAG_FAT) - new_character.mutations += M_FAT + new_character.mutations += FAT new_character.overeatduration = 600 // Max overeat if(client.prefs.disabilities & DISABILITY_FLAG_EPILEPTIC) @@ -529,7 +504,9 @@ if(client.prefs.disabilities & DISABILITY_FLAG_DEAF) new_character.dna.SetSEState(DEAFBLOCK,1,1) new_character.sdisabilities |= DEAF - + + chosen_species.handle_dna(new_character) + domutcheck(new_character) new_character.dna.UpdateSE() diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm index af932fe7a39..2c5e2b417c6 100644 --- a/code/modules/mob/new_player/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories.dm @@ -598,11 +598,37 @@ icon_state = "vox_shortquills" species_allowed = list("Vox") + vox_crestedquills + name = "Crested Vox Quills" + icon_state = "vox_crestedquills" + species_allowed = list("Vox") + + vox_tielquills + name = "Vox Tiel Quills" + icon_state = "vox_tielquills" + species_allowed = list("Vox") + + vox_emperorquills + name = "Vox Emperor Quills" + icon_state = "vox_emperorquills" + species_allowed = list("Vox") + + vox_keelquills + name = "Vox Keel Quills" + icon_state = "vox_keelquills" + species_allowed = list("Vox") + + vox_keetquills + name = "Vox Keet Quills" + icon_state = "vox_keetquills" + species_allowed = list("Vox") + + /datum/sprite_accessory/facial_hair taj_sideburns name = "Tajara Sideburns" - icon_state = "facial_mutton" + icon_state = "facial_sideburns" species_allowed = list("Tajaran") taj_mutton diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index 41612819446..38328b16bb7 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -9,114 +9,97 @@ /mob/verb/say_verb(message as text) set name = "Say" set category = "IC" + + //Let's try to make users fix their errors - we try to detect single, out-of-place letters and 'unintended' words + /* + var/first_letter = copytext(message,1,2) + if((copytext(message,2,3) == " " && first_letter != "I" && first_letter != "A" && first_letter != ";") || cmptext(copytext(message,1,5), "say ") || cmptext(copytext(message,1,4), "me ") || cmptext(copytext(message,1,6), "looc ") || cmptext(copytext(message,1,5), "ooc ") || cmptext(copytext(message,2,6), "say ")) + var/response = alert(usr, "Do you really want to say this using the *say* verb?\n\n[message]\n", "Confirm your message", "Yes", "Edit message", "No") + if(response == "Edit message") + message = input(usr, "Please edit your message carefully:", "Edit message", message) + if(!message) + return + else if(response == "No") + return + */ + + set_typing_indicator(0) usr.say(message) /mob/verb/me_verb(message as text) set name = "Me" set category = "IC" - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) + message = strip_html_properly(message) + set_typing_indicator(0) if(use_me) usr.emote("me",usr.emote_type,message) else usr.emote(message) /mob/proc/say_dead(var/message) - var/name = src.real_name - var/alt_name = "" - - if(!src.client.holder) if(!dsay_allowed) - src << "\red Deadchat is globally muted" + src << "Deadchat is globally muted." return if(client && !(client.prefs.toggles & CHAT_DEAD)) - usr << "\red You have deadchat muted." + usr << "You have deadchat muted." return - if(mind && mind.name) - name = "[mind.name]" - else - name = real_name - if(name != real_name) - alt_name = " (died as [real_name])" - - message = src.say_quote(message) - //var/rendered = "DEAD: [name][alt_name] [message]" - var/rendered2 = null//edited - for(var/mob/M in player_list) - rendered2 = "DEAD: [name][alt_name] (Follow) [message]"//edited - if(istype(M, /mob/new_player)) - continue - if(M.client && M.client.holder && (M.client.holder.rights & R_ADMIN|R_MOD) && (M.client.prefs.toggles & CHAT_DEAD)) // Show the message to admins/mods with deadchat toggled on - M << rendered2 //Admins can hear deadchat, if they choose to, no matter if they're blind/deaf or not. - - else if(M.client && M.stat == DEAD && (M.client.prefs.toggles & CHAT_DEAD)) // Show the message to regular ghosts with deadchat toggled on. - M.show_message(rendered2, 2) //Takes into account blindness and such. - return + say_dead_direct("[pick("complains","moans","whines","laments","blubbers")], \"[message]\"", src) /mob/proc/say_understands(var/mob/other,var/datum/language/speaking = null) - if(!other) - return 1 - //Universal speak makes everything understandable, for obvious reasons. - if(other.universal_speak || src.universal_speak || src.universal_understand) - return 1 - if (src.stat == 2) + if (src.stat == 2) //Dead return 1 - if(!speaking) //Handle languages later - if(other.universal_speak || src.universal_speak) + //Universal speak makes everything understandable, for obvious reasons. + else if(src.universal_speak || src.universal_understand) + return 1 + + //Languages are handled after. + if (!speaking) + if(!other) + return 1 + if(other.universal_speak) return 1 if(isAI(src) && ispAI(other)) return 1 if (istype(other, src.type) || istype(src, other.type)) return 1 - if (istype(other, /mob/living/carbon/human) && (istype(src, /mob/living/carbon/human) || istype(src, /mob/living/silicon/pai))) - return 1 - if(istype(other, /mob/living/carbon/alien) && istype(src, /mob/living/carbon/alien)) - return 1 return 0 - for(var/datum/language/L in src.languages) //Handling languages + if(speaking.flags & INNATE) + return 1 + + //Language check. + for(var/datum/language/L in src.languages) if(speaking.name == L.name) return 1 return 0 -/mob/proc/say_quote(var/text,var/datum/language/speaking) +/* + ***Deprecated*** + let this be handled at the hear_say or hear_radio proc + This is left in for robot speaking when humans gain binary channel access until I get around to rewriting + robot_talk() proc. + There is no language handling build into it however there is at the /mob level so we accept the call + for it but just ignore it. +*/ - if(!text) - return "says, \"...\""; //not the best solution, but it will stop a large number of runtimes. The cause is somewhere in the Tcomms code - //tcomms code is still runtiming somewhere here - var/ending = copytext(text, length(text)) +/mob/proc/say_quote(var/message, var/datum/language/speaking = null) + var/verb = "says" + var/ending = copytext(message, length(message)) + if(ending=="!") + verb=pick("exclaims","shouts","yells") + else if(ending=="?") + verb="asks" - var/speechverb = "" + return verb - if (speaking) - speechverb = "[speaking.speech_verb], \"" - else if(speak_emote && speak_emote.len) - speechverb = "[pick(speak_emote)], \"" - else if (src.stuttering) - speechverb = "stammers, \"" - else if (src.slurring) - speechverb = "slurrs, \"" - else if (ending == "?") - speechverb = "asks, \"" - else if (ending == "!") - speechverb = "exclaims, \"" - else if(isliving(src)) - var/mob/living/L = src - if (L.getBrainLoss() >= 60) - speechverb = "gibbers, \"" - else - speechverb = "says, \"" - else - speechverb = "says, \"" - - return "[speechverb][text]\"" /mob/proc/emote(var/act, var/type, var/message) if(act == "me") @@ -133,21 +116,34 @@ /mob/proc/say_test(var/text) var/ending = copytext(text, length(text)) if (ending == "?") - if(isalien(src)) - return "A1" - if(isrobot(src)) - return "R1" - else - return "1" + return "1" else if (ending == "!") - if(isalien(src)) - return "A2" - if(isrobot(src)) - return "R2" - else - return "2" - else if(isalien(src)) - return "A0" - else if(isrobot(src)) - return "R0" + return "2" return "0" + +//parses the message mode code (e.g. :h, :w) from text, such as that supplied to say. +//returns the message mode string or null for no message mode. +//standard mode is the mode returned for the special ';' radio code. +/mob/proc/parse_message_mode(var/message, var/standard_mode="headset") + if(length(message) >= 1 && copytext(message,1,2) == ";") + return standard_mode + + if(length(message) >= 2) + var/channel_prefix = copytext(message, 1 ,3) + return department_radio_keys[channel_prefix] + + return null + +//parses the language code (e.g. :j) from text, such as that supplied to say. +//returns the language object only if the code corresponds to a language that src can speak, otherwise null. +/mob/proc/parse_language(var/message) + if(length(message) >= 1 && copytext(message,1,2) == "!") + return all_languages["Noise"] + + if(length(message) >= 2) + var/language_prefix = lowertext(copytext(message, 1 ,3)) + var/datum/language/L = language_keys[language_prefix] + if (can_speak(L)) + return L + + return null diff --git a/code/modules/mob/spirit/cultnet.dm b/code/modules/mob/spirit/cultnet.dm index df0cd57ff5d..c3f37f8fdd1 100644 --- a/code/modules/mob/spirit/cultnet.dm +++ b/code/modules/mob/spirit/cultnet.dm @@ -19,54 +19,6 @@ It reuses a lot of code from the AIEye cameraNetwork. In order to work properly, if (vp) return TRUE return FALSE - - -/datum/visibility_chunk/cult/validViewpoint(var/atom/viewpoint) - var/turf/point = locate(src.x + 8, src.y + 8, src.z) - if(get_dist(point, viewpoint) > 24) - return FALSE - - if (isCultRune(viewpoint) || isCultViewpoint(viewpoint)) - return viewpoint:can_use() - return FALSE - - -/datum/visibility_chunk/cult/getVisibleTurfsForViewpoint(var/viewpoint) - var/obj/effect/rune/rune = viewpoint - if (rune) - return rune.can_see() - var/obj/cult_viewpoint/cvp = viewpoint - if (cvp) - return cvp.can_see() - return null - - -/datum/visibility_chunk/cult/findNearbyViewpoints() - for(var/obj/cult_viewpoint/vp in range(16, locate(x + 8, y + 8, z))) - if(vp.can_use()) - viewpoints += vp - for(var/obj/effect/rune/rune in range(16, locate(x + 8, y + 8, z))) - viewpoints += rune - - -/datum/visibility_network/cult - ChunkType = /datum/visibility_chunk/cult - - -/datum/visibility_network/cult/validViewpoint(var/viewpoint) - if (isCultRune(viewpoint) || isCultViewpoint(viewpoint)) - return viewpoint:can_use() - return FALSE - -/datum/visibility_network/cult/getViewpointFromMob(var/mob/currentMob) - for(var/obj/cult_viewpoint/currentView in currentMob) - return currentView - return FALSE - - -/datum/visibility_interface/cult - chunk_type = /datum/visibility_chunk/cult - /* RUNE JUNK diff --git a/code/modules/mob/spirit/movement.dm b/code/modules/mob/spirit/movement.dm index bd794b6fd2b..b5ac53fbeae 100644 --- a/code/modules/mob/spirit/movement.dm +++ b/code/modules/mob/spirit/movement.dm @@ -52,7 +52,6 @@ mob/spirit/proc/Spirit_Move(direct) mob/spirit/setLoc(var/T) T = get_turf(T) loc = T - cultNetwork.visibility(src) mob/spirit/verb/toggle_acceleration() set category = "Spirit" diff --git a/code/modules/mob/spirit/spirit.dm b/code/modules/mob/spirit/spirit.dm index ce7080b744c..c90f0f569b7 100644 --- a/code/modules/mob/spirit/spirit.dm +++ b/code/modules/mob/spirit/spirit.dm @@ -38,9 +38,6 @@ mob/spirit/New() loc = pick(latejoin) - // hook them to the cult visibility network - visibility_interface = new /datum/visibility_interface/cult(src) - // no nameless spirits if (!name) name = "Boogyman" diff --git a/code/modules/mob/spirit/viewpoint.dm b/code/modules/mob/spirit/viewpoint.dm index b4bd911ea1c..0cd54451361 100644 --- a/code/modules/mob/spirit/viewpoint.dm +++ b/code/modules/mob/spirit/viewpoint.dm @@ -18,9 +18,6 @@ var/obj/cult_viewpoint/list/cult_viewpoints = list() /obj/cult_viewpoint/New(var/mob/target) owner = target //src.loc = owner - owner.addToVisibilityNetwork(cultNetwork) - cultNetwork.viewpoints+=src - cultNetwork.addViewpoint(src) cult_viewpoints+=src //handle_missing_mask() ..() @@ -28,10 +25,7 @@ var/obj/cult_viewpoint/list/cult_viewpoints = list() /obj/cult_viewpoint/Del() processing_objects.Remove(src) - cultNetwork.viewpoints-=src - cultNetwork.removeViewpoint(src) cult_viewpoints-=src - owner.removeFromVisibilityNetwork(cultNetwork) ..() return @@ -134,6 +128,8 @@ var/obj/cult_viewpoint/list/cult_viewpoints = list() /obj/cult_viewpoint/proc/get_display_name() + if(istype(src,/obj/effect/rune)) + return name if (!owner) return if (cult_name) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 29baaab6f11..c90ebae7328 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -10,7 +10,7 @@ for(var/obj/item/W in src) if (W==w_uniform) // will be torn continue - drop_from_inventory(W) + unEquip(W) regenerate_icons() monkeyizing = 1 canmove = 0 @@ -73,14 +73,14 @@ if (monkeyizing) return for(var/obj/item/W in src) - drop_from_inventory(W) + unEquip(W) monkeyizing = 1 canmove = 0 icon = null invisibility = 101 return ..() -/mob/proc/AIize(move=1) +/mob/proc/AIize() if(client) src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // stop the jams for AIs var/mob/living/silicon/ai/O = new (loc,,,1)//No MMI but safety is in effect. @@ -93,52 +93,40 @@ else O.key = key - if(move) - var/obj/loc_landmark + var/obj/loc_landmark + for(var/obj/effect/landmark/start/sloc in landmarks_list) + if (sloc.name != "AI") + continue + if (locate(/mob/living) in sloc.loc) + continue + loc_landmark = sloc + if (!loc_landmark) + for(var/obj/effect/landmark/tripai in landmarks_list) + if (tripai.name == "tripai") + if(locate(/mob/living) in tripai.loc) + continue + loc_landmark = tripai + if (!loc_landmark) + O << "Oh god sorry we can't find an unoccupied AI spawn location, so we're spawning you on top of someone." for(var/obj/effect/landmark/start/sloc in landmarks_list) - if (sloc.name != "AI") - continue - if ((locate(/mob/living) in sloc.loc) || (locate(/obj/structure/AIcore) in sloc.loc)) - continue - loc_landmark = sloc - if (!loc_landmark) - for(var/obj/effect/landmark/tripai in landmarks_list) - if (tripai.name == "tripai") - if((locate(/mob/living) in tripai.loc) || (locate(/obj/structure/AIcore) in tripai.loc)) - continue - loc_landmark = tripai - if (!loc_landmark) - O << "Oh god sorry we can't find an unoccupied AI spawn location, so we're spawning you on top of someone." - for(var/obj/effect/landmark/start/sloc in landmarks_list) - if (sloc.name == "AI") - loc_landmark = sloc + if (sloc.name == "AI") + loc_landmark = sloc - O.loc = loc_landmark.loc - for (var/obj/item/device/radio/intercom/comm in O.loc) - comm.ai += O + O.loc = loc_landmark.loc + for (var/obj/item/device/radio/intercom/comm in O.loc) + comm.ai += O - O << "You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras)." - O << "To look at other parts of the station, click on yourself to get a camera menu." - O << "While observing through a camera, you can use most (networked) devices which you can see, such as computers, APCs, intercoms, doors, etc." - O << "To use something, simply click on it." - O << {"Use say ":b to speak to your cyborgs through binary."} - if (!(ticker && ticker.mode && (O.mind in ticker.mode.malf_ai))) - O.show_laws() - O << "These laws may be changed by other players, or by you being the traitor." + O.on_mob_init() - O.verbs += /mob/living/silicon/ai/proc/show_laws_verb - O.verbs += /mob/living/silicon/ai/proc/ai_statuschange - - O.job = "AI" + O.add_ai_verbs() O.rename_self("ai",1) - spawn(0) - del(src) - return O - + . = O + qdel(src) + /mob/living/carbon/human/make_into_mask(var/should_gib = 0) for(var/t in organs) - del(t) + qdel(t) return ..(should_gib) @@ -150,7 +138,7 @@ if(!should_remove_items) for(var/obj/item/W in src) - drop_from_inventory(W) + unEquip(W) var/mob/spirit/mask/new_spirit = new() @@ -193,7 +181,7 @@ if (monkeyizing) return for(var/obj/item/W in src) - drop_from_inventory(W) + unEquip(W) regenerate_icons() monkeyizing = 1 canmove = 0 @@ -249,7 +237,7 @@ if (monkeyizing) return for(var/obj/item/W in src) - drop_from_inventory(W) + unEquip(W) regenerate_icons() monkeyizing = 1 canmove = 0 @@ -280,7 +268,7 @@ if (monkeyizing) return for(var/obj/item/W in src) - drop_from_inventory(W) + unEquip(W) regenerate_icons() monkeyizing = 1 canmove = 0 @@ -315,7 +303,7 @@ if (monkeyizing) return for(var/obj/item/W in src) - drop_from_inventory(W) + unEquip(W) regenerate_icons() monkeyizing = 1 canmove = 0 @@ -345,7 +333,7 @@ if(monkeyizing) return for(var/obj/item/W in src) - drop_from_inventory(W) + unEquip(W) regenerate_icons() monkeyizing = 1 @@ -434,7 +422,13 @@ if(ispath(MP, /mob/living/simple_animal/pony)) return 1 // ZOMG PONIES WHEEE if(ispath(MP, /mob/living/simple_animal/fox)) - return 1 + return 1 + if(ispath(MP, /mob/living/simple_animal/chick)) + return 1 + if(ispath(MP, /mob/living/simple_animal/pug)) + return 1 + if(ispath(MP, /mob/living/simple_animal/butterfly)) + return 1 //Not in here? Must be untested! return 0 @@ -459,7 +453,13 @@ if(ispath(MP, /mob/living/simple_animal/pony)) return 1 if(ispath(MP, /mob/living/simple_animal/fox)) - return 1 + return 1 + if(ispath(MP, /mob/living/simple_animal/chick)) + return 1 + if(ispath(MP, /mob/living/simple_animal/pug)) + return 1 + if(ispath(MP, /mob/living/simple_animal/butterfly)) + return 1 //Antag Creatures! /* if(ispath(MP, /mob/living/simple_animal/hostile/carp) && !jobban_isbanned(src, "Syndicate")) diff --git a/code/modules/mob/typing_indicator.dm b/code/modules/mob/typing_indicator.dm new file mode 100644 index 00000000000..138fd093eaf --- /dev/null +++ b/code/modules/mob/typing_indicator.dm @@ -0,0 +1,91 @@ +#define TYPING_INDICATOR_LIFETIME 30 * 10 //grace period after which typing indicator disappears regardless of text in chatbar + +mob/var/hud_typing = 0 //set when typing in an input window instead of chatline +mob/var/typing +mob/var/last_typed +mob/var/last_typed_time + +var/global/image/typing_indicator + +/mob/proc/set_typing_indicator(var/state) + + if(!typing_indicator) + typing_indicator = image('icons/mob/talk.dmi',null,"typing") + + if(ishuman(src)) + var/mob/living/carbon/human/H = src + if(H.sdisabilities & MUTE || H.silent) + overlays -= typing_indicator + return + + if(client) + if((client.prefs.toggles & SHOW_TYPING) || stat != CONSCIOUS || is_muzzled()) + overlays -= typing_indicator + else + if(state) + if(!typing) + overlays += typing_indicator + typing = 1 + else + if(typing) + overlays -= typing_indicator + typing = 0 + return state + +/mob/verb/say_wrapper() + set name = ".Say" + set hidden = 1 + + set_typing_indicator(1) + hud_typing = 1 + var/message = input("","say (text)") as null|text + hud_typing = 0 + set_typing_indicator(0) + if(message) + say_verb(message) + +/mob/verb/me_wrapper() + set name = ".Me" + set hidden = 1 + + set_typing_indicator(1) + hud_typing = 1 + var/message = input("","me (text)") as null|text + hud_typing = 0 + set_typing_indicator(0) + if(message) + me_verb(message) + +/mob/proc/handle_typing_indicator() + if(client) + if(!(client.prefs.toggles & SHOW_TYPING) && !hud_typing) + var/temp = winget(client, "input", "text") + + if (temp != last_typed) + last_typed = temp + last_typed_time = world.time + + if (world.time > last_typed_time + TYPING_INDICATOR_LIFETIME) + set_typing_indicator(0) + return + if(length(temp) > 5 && findtext(temp, "Say \"", 1, 7)) + set_typing_indicator(1) + else if(length(temp) > 3 && findtext(temp, "Me ", 1, 5)) + set_typing_indicator(1) + + else + set_typing_indicator(0) + +/client/verb/typing_indicator() + set name = "Show/Hide Typing Indicator" + set category = "Preferences" + set desc = "Toggles showing an indicator when you are typing emote or say message." + prefs.toggles ^= SHOW_TYPING + prefs.save_preferences(src) + src << "You will [(prefs.toggles & SHOW_TYPING) ? "no longer" : "now"] display a typing indicator." + + // Clear out any existing typing indicator. + if(prefs.toggles & SHOW_TYPING) + if(istype(mob)) mob.set_typing_indicator(0) + + feedback_add_details("admin_verb","TID") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! \ No newline at end of file diff --git a/code/modules/nano/JSON Writer.dm b/code/modules/nano/JSON Writer.dm index 3cd3520f177..f4c74d35ebb 100644 --- a/code/modules/nano/JSON Writer.dm +++ b/code/modules/nano/JSON Writer.dm @@ -1,7 +1,7 @@ json_writer proc - WriteObject(list/L) + WriteObject(list/L, cached_data = null) . = "{" var/i = 1 for(var/k in L) @@ -9,6 +9,8 @@ json_writer . += {"\"[k]\":[write(val)]"} if(i++ < L.len) . += "," + if(cached_data) + . = copytext(., 1, lentext(.)) + ",\"cached\":[cached_data]}" .+= "}" write(val) diff --git a/code/modules/nano/_JSON.dm b/code/modules/nano/_JSON.dm index 5692e643baa..4f70e6e664a 100644 --- a/code/modules/nano/_JSON.dm +++ b/code/modules/nano/_JSON.dm @@ -7,6 +7,6 @@ proc var/static/json_reader/_jsonr = new() return _jsonr.ReadObject(_jsonr.ScanJson(json)) - list2json(list/L) + list2json(list/L, var/cached_data = null) var/static/json_writer/_jsonw = new() - return _jsonw.WriteObject(L) + return _jsonw.WriteObject(L, cached_data) diff --git a/code/modules/nano/modules/crew_monitor.dm b/code/modules/nano/modules/crew_monitor.dm new file mode 100644 index 00000000000..c27c0446395 --- /dev/null +++ b/code/modules/nano/modules/crew_monitor.dm @@ -0,0 +1,88 @@ +/obj/nano_module/crew_monitor + name = "Crew monitor" + var/list/tracked = new + +/obj/nano_module/crew_monitor/Topic(href, href_list) + if(..()) return + var/turf/T = get_turf(src) + if (!T || !(T.z in config.player_levels)) + usr << "Unable to establish a connection: You're too far away from the station!" + return 0 + if(href_list["close"] ) + var/mob/user = usr + var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main") + usr.unset_machine() + ui.close() + return 0 + if(href_list["update"]) + src.updateDialog() + return 1 + +/obj/nano_module/crew_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) + src.scan() + + var/data[0] + var/turf/T = get_turf(src) + var/list/crewmembers = list() + for(var/obj/item/clothing/under/C in src.tracked) + + var/turf/pos = get_turf(C) + + if((C) && (C.has_sensor) && (pos) && (T && pos.z == T.z) && (C.sensor_mode != SUIT_SENSOR_OFF)) + if(istype(C.loc, /mob/living/carbon/human)) + + var/mob/living/carbon/human/H = C.loc + if(H.w_uniform != C) + continue + + var/list/crewmemberData = list("dead"=0, "oxy"=-1, "tox"=-1, "fire"=-1, "brute"=-1, "area"="", "x"=-1, "y"=-1) + + crewmemberData["sensor_type"] = C.sensor_mode + crewmemberData["name"] = H.get_authentification_name(if_no_id="Unknown") + crewmemberData["rank"] = H.get_authentification_rank(if_no_id="Unknown", if_no_job="No Job") + crewmemberData["assignment"] = H.get_assignment(if_no_id="Unknown", if_no_job="No Job") + + if(C.sensor_mode >= SUIT_SENSOR_BINARY) + crewmemberData["dead"] = H.stat > 1 + + if(C.sensor_mode >= SUIT_SENSOR_VITAL) + crewmemberData["oxy"] = round(H.getOxyLoss(), 1) + crewmemberData["tox"] = round(H.getToxLoss(), 1) + crewmemberData["fire"] = round(H.getFireLoss(), 1) + crewmemberData["brute"] = round(H.getBruteLoss(), 1) + + if(C.sensor_mode >= SUIT_SENSOR_TRACKING) + var/area/A = get_area(H) + crewmemberData["area"] = sanitize(A.name) + crewmemberData["x"] = pos.x + crewmemberData["y"] = pos.y + + crewmembers[++crewmembers.len] = crewmemberData + + crewmembers = sortByKey(crewmembers, "name") + + data["crewmembers"] = crewmembers + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + ui = new(user, src, ui_key, "crew_monitor.tmpl", "Crew Monitoring Computer", 900, 800) + + // adding a template with the key "mapContent" enables the map ui functionality + ui.add_template("mapContent", "crew_monitor_map_content.tmpl") + // adding a template with the key "mapHeader" replaces the map header content + ui.add_template("mapHeader", "crew_monitor_map_header.tmpl") + + ui.set_initial_data(data) + ui.open() + + // should make the UI auto-update; doesn't seem to? + ui.set_auto_update(1) + +/obj/nano_module/crew_monitor/proc/scan() + for(var/mob/living/carbon/human/H in mob_list) + if(istype(H.w_uniform, /obj/item/clothing/under)) + var/obj/item/clothing/under/C = H.w_uniform + if (C.has_sensor) + tracked |= C + return 1 diff --git a/code/modules/nano/nanoexternal.dm b/code/modules/nano/nanoexternal.dm index 3e5a011d5fa..b029019f1a3 100644 --- a/code/modules/nano/nanoexternal.dm +++ b/code/modules/nano/nanoexternal.dm @@ -31,18 +31,13 @@ * ui_interact is currently defined for /atom/movable * * @param user /mob The mob who is interacting with this ui -<<<<<<< HEAD * @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main") * @param ui /datum/nanoui This parameter is passed by the nanoui process() proc when updating an open ui -======= - * @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main") - * @param ui /datum/nanoui This parameter is passed by the nanoui process() proc when updating an open ui * @param force_open boolean Force the UI to (re)open, even if it's already open ->>>>>>> 7e7e6cd... Continued work in progress on a major revision of the NanoUI templating system. * * @return nothing */ -/atom/movable/proc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/atom/movable/proc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/nano_ui/master_ui = null, var/datum/topic_state/custom_state = null) return // Used by the Nano UI Manager (/datum/nanomanager) to track UIs opened by this mob diff --git a/code/modules/nano/nanointeraction.dm b/code/modules/nano/nanointeraction.dm new file mode 100644 index 00000000000..6deadd1927b --- /dev/null +++ b/code/modules/nano/nanointeraction.dm @@ -0,0 +1,120 @@ +/atom/movable/proc/nano_host() + return src + +/obj/nano_module/nano_host() + return loc + + +/atom/movable/proc/CanUseTopic(var/mob/user, href_list, var/datum/topic_state/custom_state) + return user.can_use_topic(nano_host(), custom_state) + + +/mob/proc/can_use_topic(var/mob/user, var/datum/topic_state/custom_state) + return STATUS_CLOSE // By default no mob can do anything with NanoUI + +/mob/dead/observer/can_use_topic() + if(check_rights(R_ADMIN, 0, src)) + return STATUS_INTERACTIVE // Admins are more equal + return STATUS_UPDATE // Ghosts can view updates + +/mob/living/silicon/pai/can_use_topic(var/src_object) + if(src_object == src && !stat) + return STATUS_INTERACTIVE + else + return ..() + +/mob/living/silicon/robot/can_use_topic(var/src_object, var/datum/topic_state/custom_state) + if(stat || !client) + return STATUS_CLOSE + if(lockcharge || stunned || weakened) + return STATUS_DISABLED + // robots can interact with things they can see within their view range + if(!(custom_state.flags & NANO_IGNORE_DISTANCE) && (src_object in view(src))) + return STATUS_INTERACTIVE // interactive (green visibility) + return STATUS_DISABLED // no updates, completely disabled (red visibility) + +/mob/living/silicon/robot/syndicate/can_use_topic(var/src_object) + . = ..() + if(. != STATUS_INTERACTIVE) + return + + if(z in config.admin_levels) // Syndicate borgs can interact with everything on the admin level + return STATUS_INTERACTIVE + if(istype(get_area(src), /area/syndicate_station)) // If elsewhere, they can interact with everything on the syndicate shuttle + return STATUS_INTERACTIVE + if(istype(src_object, /obj/machinery)) // Otherwise they can only interact with emagged machinery + var/obj/machinery/Machine = src_object + if(Machine.emagged) + return STATUS_INTERACTIVE + return STATUS_UPDATE + +/mob/living/silicon/ai/can_use_topic(var/src_object) + if(!client || check_unable(1)) + return STATUS_CLOSE + // Prevents the AI from using Topic on admin levels (by for example viewing through the court/thunderdome cameras) + // unless it's on the same level as the object it's interacting with. + var/turf/T = get_turf(src_object) + if(!T || !(z == T.z || (T.z in config.player_levels))) + return STATUS_CLOSE + + // If an object is in view then we can interact with it + if(src_object in view(client.view, src)) + return STATUS_INTERACTIVE + + // If we're installed in a chassi, rather than transfered to an inteliCard or other container, then check if we have camera view + if(is_in_chassis()) + //stop AIs from leaving windows open and using then after they lose vision + //apc_override is needed here because AIs use their own APC when powerless + if(cameranet && !cameranet.checkTurfVis(get_turf(src_object))) + return apc_override ? STATUS_INTERACTIVE : STATUS_CLOSE + return STATUS_INTERACTIVE + + return STATUS_CLOSE + +/mob/living/proc/shared_living_nano_interaction(var/src_object) + if (src.stat != CONSCIOUS) + return STATUS_CLOSE // no updates, close the interface + else if (restrained() || lying || stat || stunned || weakened) + return STATUS_UPDATE // update only (orange visibility) + return STATUS_INTERACTIVE + +/mob/living/proc/shared_living_nano_distance(var/atom/movable/src_object) + if(!isturf(src_object.loc)) + if(src_object.loc == src) // Item in the inventory + return STATUS_INTERACTIVE + if(src.contents.Find(src_object.loc)) // A hidden uplink inside an item + return STATUS_INTERACTIVE + + if (!(src_object in view(4, src))) // If the src object is not in visable, disable updates + return STATUS_CLOSE + + var/dist = get_dist(src_object, src) + if (dist <= 1) + return STATUS_INTERACTIVE // interactive (green visibility) + else if (dist <= 2) + return STATUS_UPDATE // update only (orange visibility) + else if (dist <= 4) + return STATUS_DISABLED // no updates, completely disabled (red visibility) + return STATUS_CLOSE + +/mob/living/can_use_topic(var/src_object, var/datum/topic_state/custom_state) + . = shared_living_nano_interaction(src_object) + if(. == STATUS_INTERACTIVE && !(custom_state.flags & NANO_IGNORE_DISTANCE)) + . = shared_living_nano_distance(src_object) + if(STATUS_INTERACTIVE) + return STATUS_UPDATE + +/mob/living/carbon/human/can_use_topic(var/src_object, var/datum/topic_state/custom_state) + . = shared_living_nano_interaction(src_object) + if(. == STATUS_INTERACTIVE && !(custom_state.flags & NANO_IGNORE_DISTANCE)) + . = shared_living_nano_distance(src_object) + if(. == STATUS_UPDATE && (TK in mutations)) // If we have telekinesis and remain close enough, allow interaction. + return STATUS_INTERACTIVE + +/var/global/datum/topic_state/default_state = new() + +/datum/topic_state + var/flags = 0 + +/datum/topic_state/proc/href_list(var/mob/user) + return list() \ No newline at end of file diff --git a/code/modules/nano/nanomanager.dm b/code/modules/nano/nanomanager.dm index 2ce8de3b08b..1fd76dcf726 100644 --- a/code/modules/nano/nanomanager.dm +++ b/code/modules/nano/nanomanager.dm @@ -1,8 +1,9 @@ // This is the window/UI manager for Nano UI // There should only ever be one (global) instance of nanomanger /datum/nanomanager - // the list of current open /nanoui UIs + // a list of current open /nanoui UIs, grouped by src_object and ui_key var/open_uis[0] + // a list of current open /nanoui UIs, not grouped, for use in processing var/list/processing_uis = list() // a list of asset filenames which are to be sent to the client on user logon var/list/asset_files = list() @@ -26,7 +27,8 @@ filenames = flist(path) for(var/filename in filenames) if(copytext(filename, length(filename)) != "/") // filenames which end in "/" are actually directories, which we want to ignore - asset_files.Add(file(path + filename)) // add this file to asset_files for sending to clients when they connect + if(fexists(path + filename)) + asset_files.Add(fcopy_rsc(path + filename)) // add this file to asset_files for sending to clients when they connect return @@ -85,7 +87,7 @@ /** * Update all /nanoui uis attached to src_object * - * @param src_object /obj|/mob The obj or mob which the uis belong to + * @param src_object /obj|/mob The obj or mob which the uis are attached to * * @return int The number of uis updated */ @@ -97,7 +99,7 @@ var/update_count = 0 for (var/ui_key in open_uis[src_object_key]) for (var/datum/nanoui/ui in open_uis[src_object_key][ui_key]) - if(ui && ui.src_object && ui.user) + if(ui && ui.src_object && ui.user && ui.src_object.nano_host()) ui.process(1) update_count++ return update_count @@ -184,7 +186,8 @@ return 0 // wasn't open processing_uis.Remove(ui) - ui.user.open_uis.Remove(ui) + if(ui.user) // Sanity check in case a user has been deleted (say a blown up borg watching the alarm interface) + ui.user.open_uis.Remove(ui) var/list/uis = open_uis[src_object_key][ui.ui_key] uis.Remove(ui) @@ -245,4 +248,3 @@ for(var/file in asset_files) client << browse_rsc(file) // send the file to the client - return 1 // success diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm index 54ff6b70b01..0a588e9b51a 100644 --- a/code/modules/nano/nanoui.dm +++ b/code/modules/nano/nanoui.dm @@ -6,11 +6,6 @@ nanoui class (or whatever Byond calls classes) nanoui is used to open and update nano browser uis **********************************************************/ - -#define STATUS_INTERACTIVE 2 // GREEN Visability -#define STATUS_UPDATE 1 // ORANGE Visability -#define STATUS_DISABLED 0 // RED Visability - /datum/nanoui // the user who opened this ui var/mob/user @@ -18,8 +13,6 @@ nanoui is used to open and update nano browser uis var/atom/movable/src_object // the title of this ui var/title - // /vg/ - Whether to write debug information to nano/debug.html - var/writeDebug=TRUE // the key of this ui, this is to allow multiple (different) uis for each src_object var/ui_key // window_id is used as the window name/identifier for browse and onclose @@ -59,8 +52,12 @@ nanoui is used to open and update nano browser uis // the current status/visibility of the ui var/status = STATUS_INTERACTIVE - // Only allow users with a certain user.stat to get updates. Defaults to 0 (concious) - var/allowed_user_stat = 0 // -1 = ignore, 0 = alive, 1 = unconcious or alive, 2 = dead concious or alive + // Relationship between a master interface and its children. Used in update_status + var/datum/nanoui/master_ui + var/list/datum/nanoui/children = list() + var/datum/topic_state/custom_state = null + + var/cached_data = null /** * Create a new nanoui instance. @@ -76,17 +73,22 @@ nanoui is used to open and update nano browser uis * * @return /nanoui new nanoui object */ -/datum/nanoui/New(nuser, nsrc_object, nui_key, ntemplate_filename, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null) +/datum/nanoui/New(nuser, nsrc_object, nui_key, ntemplate_filename, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null, var/datum/nanoui/master_ui = null, var/datum/topic_state/custom_state = default_state) user = nuser src_object = nsrc_object ui_key = nui_key window_id = "[ui_key]\ref[src_object]" + src.master_ui = master_ui + if(master_ui) + master_ui.children += src + src.custom_state = custom_state + // add the passed template filename as the "main" template, this is required add_template("main", ntemplate_filename) if (ntitle) - title = ntitle + title = sanitize(ntitle) if (nwidth) width = nwidth if (nheight) @@ -140,36 +142,14 @@ nanoui is used to open and update nano browser uis * @return nothing */ /datum/nanoui/proc/update_status(var/push_update = 0) - if (istype(user, /mob/living/silicon/ai)) - set_status(STATUS_INTERACTIVE, push_update) // interactive (green visibility) - else if (istype(user, /mob/living/silicon/robot)) - if (src_object in view(7, user)) // robots can see and interact with things they can see within 7 tiles - set_status(STATUS_INTERACTIVE, push_update) // interactive (green visibility) - else - set_status(STATUS_DISABLED, push_update) // no updates, completely disabled (red visibility) - else - var/dist = get_dist(src_object, user) + var/atom/movable/host = src_object.nano_host() + var/new_status = host.CanUseTopic(user, list(), custom_state) + if(master_ui) + new_status = min(new_status, master_ui.status) - if (dist > 4) - close() - return - - if ((allowed_user_stat > -1) && (user.stat > allowed_user_stat)) - set_status(STATUS_DISABLED, push_update) // no updates, completely disabled (red visibility) - else if (user.restrained() || user.lying) - set_status(STATUS_UPDATE, push_update) // update only (orange visibility) - else if (istype(src_object, /obj/item/device/uplink/hidden)) // You know what if they have the uplink open let them use the UI - set_status(STATUS_INTERACTIVE, push_update) // Will build in distance checks on the topics for sanity. - else if (!(src_object in view(4, user))) // If the src object is not in visable, set status to 0 - set_status(STATUS_DISABLED, push_update) // interactive (green visibility) - else if (dist <= 1) - set_status(STATUS_INTERACTIVE, push_update) // interactive (green visibility) - else if (dist <= 2) - set_status(STATUS_UPDATE, push_update) // update only (orange visibility) - else if (istype(src_object, /obj/item/device/uplink/hidden)) // You know what if they have the uplink open let them use the UI - set_status(STATUS_INTERACTIVE, push_update) // Will build in distance checks on the topics for sanity. - else if (dist <= 4) - set_status(STATUS_DISABLED, push_update) // no updates, completely disabled (red visibility) + set_status(new_status, push_update) + if(new_status == STATUS_CLOSE) + close() /** * Set the ui to auto update (every master_controller tick) @@ -325,7 +305,7 @@ nanoui is used to open and update nano browser uis */ /datum/nanoui/proc/set_show_map(nstate) show_map = nstate - + /** * Toggle showing the map ui * @@ -370,7 +350,7 @@ nanoui is used to open and update nano browser uis template_data_json = list2json(templates) var/list/send_data = get_send_data(initial_data) - var/initial_data_json = list2json(send_data) + var/initial_data_json = list2json(send_data, cached_data) var/url_parameters_json = list2json(list("src" = "\ref[src]")) @@ -412,18 +392,15 @@ nanoui is used to open and update nano browser uis * @return nothing */ /datum/nanoui/proc/open() - var/window_size = "" if (width && height) window_size = "size=[width]x[height];" update_status(0) - var/html=get_html() - if(src.writeDebug) - var/f = file("nano/debug.html") - fdel(f) - f << html - user << browse(html, "window=[window_id];[window_size][window_options]") - winset(user, "mapwindow.map", "focus=true") // Return keyboard focus to map. + if(status == STATUS_CLOSE) + return + + user << browse(get_html(), "window=[window_id];[window_size][window_options]") + winset(user, "mapwindow.map", "focus=true") // return keyboard focus to map on_close_winset() //onclose(user, window_id) nanomanager.ui_opened(src) @@ -437,6 +414,8 @@ nanoui is used to open and update nano browser uis is_auto_updating = 0 nanomanager.ui_closed(src) user << browse(null, "window=[window_id]") + for(var/datum/nanoui/child in children) + child.close() /** * Set the UI window to call the nanoclose verb when the window is closed @@ -451,6 +430,19 @@ nanoui is used to open and update nano browser uis winset(user, window_id, "on-close=\"nanoclose [params]\"") +/** + * Appends already processed json txt to the list2json proc when setting initial-data and data pushes + * Used for data that is fucking huge like manifests and camera lists that doesn't change often. + * And we only want to process them when they change. + * Fuck javascript + * + * @return nothing + */ +/datum/nanoui/proc/load_cached_data(var/data) + cached_data = data + return + + /** * Push data to an already open UI window * @@ -464,7 +456,7 @@ nanoui is used to open and update nano browser uis var/list/send_data = get_send_data(data) //user << list2json(data) // used for debugging - user << output(list2params(list(list2json(send_data))),"[window_id].browser:receiveUpdateData") + user << output(list2params(list(list2json(send_data,cached_data))),"[window_id].browser:receiveUpdateData") /** * This Topic() proc is called whenever a user clicks on a link within a Nano UI @@ -483,12 +475,12 @@ nanoui is used to open and update nano browser uis if(href_list["showMap"]) set_show_map(text2num(href_list["showMap"])) map_update = 1 - + if(href_list["mapZLevel"]) set_map_z_level(text2num(href_list["mapZLevel"])) map_update = 1 - if ((src_object && src_object.Topic(href, href_list)) || map_update) + if ((src_object && src_object.Topic(href, href_list, 0, custom_state)) || map_update) nanomanager.update_uis(src_object) // update all UIs attached to src_object /** @@ -515,5 +507,4 @@ nanoui is used to open and update nano browser uis * @return nothing */ /datum/nanoui/proc/update(var/force_open = 0) - src_object.ui_interact(user, ui_key, src, force_open) - + src_object.ui_interact(user, ui_key, src, force_open, master_ui, custom_state) diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index a039a53edc6..a48b319b3f2 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -614,11 +614,11 @@ Note that amputating the affected organ does in fact remove the infection from t else organ= new /obj/item/weapon/organ/head(owner.loc, owner) owner.death() - owner.u_equip(owner.glasses) - owner.u_equip(owner.head) - owner.u_equip(owner.l_ear) - owner.u_equip(owner.r_ear) - owner.u_equip(owner.wear_mask) + owner.unEquip(owner.glasses) + owner.unEquip(owner.head) + owner.unEquip(owner.l_ear) + owner.unEquip(owner.r_ear) + owner.unEquip(owner.wear_mask) if(ARM_RIGHT) if(!spawn_limb) if(status & ORGAN_ROBOT) @@ -658,7 +658,7 @@ Note that amputating the affected organ does in fact remove the infection from t organ = new /obj/item/weapon/skeleton/r_hand(owner.loc) else organ= new /obj/item/weapon/organ/r_hand(owner.loc, owner) - owner.u_equip(owner.gloves) + owner.unEquip(owner.gloves) if(HAND_LEFT) if(!spawn_limb) if(!(status & ORGAN_ROBOT)) @@ -666,7 +666,7 @@ Note that amputating the affected organ does in fact remove the infection from t organ = new /obj/item/weapon/skeleton/l_hand(owner.loc) else organ= new /obj/item/weapon/organ/l_hand(owner.loc, owner) - owner.u_equip(owner.gloves) + owner.unEquip(owner.gloves) if(FOOT_RIGHT) if(!spawn_limb) if(!(status & ORGAN_ROBOT)) @@ -674,7 +674,7 @@ Note that amputating the affected organ does in fact remove the infection from t organ = new /obj/item/weapon/skeleton/r_foot(owner.loc) else organ= new /obj/item/weapon/organ/r_foot/(owner.loc, owner) - owner.u_equip(owner.shoes) + owner.unEquip(owner.shoes) if(FOOT_LEFT) if(!spawn_limb) if(!(status & ORGAN_ROBOT)) @@ -682,7 +682,7 @@ Note that amputating the affected organ does in fact remove the infection from t organ = new /obj/item/weapon/skeleton/l_foot(owner.loc) else organ = new /obj/item/weapon/organ/l_foot(owner.loc, owner) - owner.u_equip(owner.shoes) + owner.unEquip(owner.shoes) destspawn = 1 //Robotic limbs explode if sabotaged. @@ -724,14 +724,14 @@ Note that amputating the affected organ does in fact remove the infection from t "\The [owner.handcuffed.name] falls off of [owner.name].",\ "\The [owner.handcuffed.name] falls off you.") - owner.drop_from_inventory(owner.handcuffed) + owner.unEquip(owner.handcuffed) if (owner.legcuffed && body_part in list(FOOT_LEFT, FOOT_RIGHT, LEG_LEFT, LEG_RIGHT)) owner.visible_message(\ "\The [owner.legcuffed.name] falls off of [owner.name].",\ "\The [owner.legcuffed.name] falls off you.") - owner.drop_from_inventory(owner.legcuffed) + owner.unEquip(owner.legcuffed) /datum/organ/external/proc/bandage() var/rval = 0 @@ -842,11 +842,11 @@ Note that amputating the affected organ does in fact remove the infection from t return if(is_broken()) - owner.u_equip(c_hand) + owner.unEquip(c_hand) var/emote_scream = pick("screams in pain and", "lets out a sharp cry and", "cries out and") owner.emote("me", 1, "[(owner.species && owner.species.flags & NO_PAIN) ? "" : emote_scream ] drops what they were holding in their [hand_name]!") if(is_malfunctioning()) - owner.u_equip(c_hand) + owner.unEquip(c_hand) owner.emote("me", 1, "drops what they were holding, their [hand_name] malfunctioning!") var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() spark_system.set_up(5, 0, owner) @@ -1159,7 +1159,7 @@ obj/item/weapon/organ/head/proc/transfer_identity(var/mob/living/carbon/human/H) respawnable_list += brainmob brainmob.container = src -obj/item/weapon/organ/head/attackby(obj/item/weapon/W as obj, mob/user as mob) +obj/item/weapon/organ/head/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/scalpel)) switch(brain_op_stage) if(0) diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm index 54aac02d952..e0872804ce3 100644 --- a/code/modules/organs/organ_internal.dm +++ b/code/modules/organs/organ_internal.dm @@ -96,6 +96,7 @@ P.internal_organs = list() P.internal_organs += src H.internal_organs_by_name[name] = src + H.internal_organs |= src owner = H return @@ -196,7 +197,7 @@ src.damage += 0.2 * process_accuracy //Damaged one shares the fun else - var/datum/organ/internal/O = pick(owner.internal_organs_by_name) + var/datum/organ/internal/O = pick(owner.internal_organs) if(O) O.damage += 0.2 * process_accuracy diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm index ca128c2c10c..9773773316f 100644 --- a/code/modules/paperwork/clipboard.dm +++ b/code/modules/paperwork/clipboard.dm @@ -9,7 +9,6 @@ throw_range = 10 var/obj/item/weapon/pen/haspen //The stored pen. var/obj/item/weapon/toppaper //The topmost piece of paper. - flags = FPRINT | TABLEPASS slot_flags = SLOT_BELT /obj/item/weapon/clipboard/New() @@ -24,10 +23,10 @@ if(!M.restrained() && !M.stat) switch(over_object.name) if("r_hand") - M.u_equip(src) + M.unEquip(src) M.put_in_r_hand(src) if("l_hand") - M.u_equip(src) + M.unEquip(src) M.put_in_l_hand(src) add_fingerprint(usr) @@ -43,8 +42,8 @@ overlays += "clipboard_over" return -/obj/item/weapon/clipboard/attackby(obj/item/weapon/W as obj, mob/user as mob) - +/obj/item/weapon/clipboard/attackby(obj/item/weapon/W as obj, mob/user as mob, params) + if(istype(W, /obj/item/weapon/paper) || istype(W, /obj/item/weapon/photo)) user.drop_item() W.loc = src @@ -54,7 +53,7 @@ update_icon() else if(istype(toppaper) && istype(W, /obj/item/weapon/pen)) - toppaper.attackby(W, usr) + toppaper.attackby(W, usr, params) update_icon() return @@ -107,20 +106,20 @@ else if(href_list["write"]) var/obj/item/weapon/P = locate(href_list["write"]) - + if(P && (P.loc == src) && istype(P, /obj/item/weapon/paper) && (P == toppaper) ) - + var/obj/item/I = usr.get_active_hand() - + if(istype(I, /obj/item/weapon/pen)) - + P.attackby(I, usr) else if(href_list["remove"]) var/obj/item/P = locate(href_list["remove"]) - + if(P && (P.loc == src) && (istype(P, /obj/item/weapon/paper) || istype(P, /obj/item/weapon/photo)) ) - + P.loc = usr.loc usr.put_in_hands(P) if(P == toppaper) @@ -133,9 +132,9 @@ else if(href_list["read"]) var/obj/item/weapon/paper/P = locate(href_list["read"]) - + if(P && (P.loc == src) && istype(P, /obj/item/weapon/paper) ) - + if(!(istype(usr, /mob/living/carbon/human) || istype(usr, /mob/dead/observer) || istype(usr, /mob/living/silicon))) usr << browse("[P.name][stars(P.info)][P.stamps]", "window=[P.name]") onclose(usr, "[P.name]") diff --git a/code/modules/paperwork/fax.dm b/code/modules/paperwork/fax.dm new file mode 100644 index 00000000000..a4b13a2876f --- /dev/null +++ b/code/modules/paperwork/fax.dm @@ -0,0 +1,87 @@ +// Fax datum - holds all faxes sent during the round +var/list/faxes = list() +var/list/adminfaxes = list() + +/datum/fax + var/name = "fax" + var/from_department = null + var/to_department = null + var/origin = null + var/message = null + var/sent_by = null + var/sent_at = null + +/datum/fax/New() + faxes += src + +/datum/fax/admin + var/list/reply_to = null + +/datum/fax/admin/New() + adminfaxes += src + +// Fax panel - lets admins check all faxes sent during the round +/client/proc/fax_panel() + set name = "Fax Panel" + set category = "Event" + if(holder) + holder.fax_panel(usr) + feedback_add_details("admin_verb","FXP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + return + +/datum/admins/proc/fax_panel(var/mob/living/user) + var/html = "Refresh" + html += "Create Fax" + + html += "
" + html += "

Admin Faxes

" + html += "" + html += "" + for(var/datum/fax/admin/A in adminfaxes) + html += "" + html += "" + html += "" + html += "" + html += "" + if(A.sent_by) + var/mob/living/S = A.sent_by + html += "" + else + html += "" + html += "" + if(!A.reply_to) + if(A.from_department == "Administrator") + html += "" + else + html += "" + html += "" + else + html += "" + html += "" + html += "" + html += "
NameFrom DepartmentTo DepartmentSent AtSent ByViewReplyReplied To
[A.name][A.from_department][A.to_department][worldtime2text(A.sent_at)][S.name]UnknownViewN/AReplyN/AN/AOriginal
" + html += "
" + + html += "
" + html += "

Departmental Faxes

" + html += "" + html += "" + for(var/datum/fax/F in faxes) + html += "" + html += "" + html += "" + html += "" + html += "" + if(F.sent_by) + var/mob/living/S = F.sent_by + html += "" + else + html += "" + html += "" + html += "" + html += "
NameFrom DepartmentTo DepartmentSent AtSent ByView
[F.name][F.from_department][F.to_department][worldtime2text(F.sent_at)][S.name]UnknownView
" + html += "
" + + var/datum/browser/popup = new(user, "fax_panel", "Fax Panel", 950, 450) + popup.set_content(html) + popup.open() diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm index a727a3f59c3..f01aa60d704 100644 --- a/code/modules/paperwork/faxmachine.dm +++ b/code/modules/paperwork/faxmachine.dm @@ -1,15 +1,14 @@ var/list/obj/machinery/photocopier/faxmachine/allfaxes = list() var/list/admin_departments = list("Central Command") +var/list/hidden_admin_departments = list("Syndicate") var/list/alldepartments = list() -var/list/adminfaxes = list() //cache for faxes that have been sent to admins - /obj/machinery/photocopier/faxmachine name = "fax machine" icon = 'icons/obj/library.dmi' icon_state = "fax" insert_anim = "faxsend" - req_one_access = list(access_lawyer, access_heads, access_armory) + req_one_access = list(access_lawyer, access_heads, access_armory) use_power = 1 idle_power_usage = 30 @@ -31,140 +30,184 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins alldepartments |= department /obj/machinery/photocopier/faxmachine/attack_hand(mob/user as mob) - user.set_machine(src) + ui_interact(user) - var/dat = "Fax Machine
" +/obj/machinery/photocopier/faxmachine/attackby(obj/item/weapon/item, mob/user, params) + if(istype(item,/obj/item/weapon/card/id) && !scan) + scan(item) + else if(istype(item, /obj/item/weapon/paper) || istype(item, /obj/item/weapon/photo) || istype(item, /obj/item/weapon/paper_bundle)) + ..() + nanomanager.update_uis(src) + else + return ..() - var/scan_name +/obj/machinery/photocopier/faxmachine/emag_act(user as mob) + if(!emagged) + emagged = 1 + user << "The transmitters realign to an unknown source!" + else + user << "You swipe the card through [src], but nothing happens." + +/obj/machinery/photocopier/faxmachine/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] if(scan) - scan_name = scan.name + data["scan_name"] = scan.name else - scan_name = "--------" - - dat += "Confirm Identity: [scan_name]
" - - if(authenticated) - dat += "{Log Out}" + data["scan_name"] = "-----" + data["authenticated"] = authenticated + if(!authenticated) + data["network"] = "Disconnected" + else if(!emagged) + data["network"] = "Central Command Quantum Entanglement Network" else - dat += "{Log In}" - - dat += "
" - - if(authenticated) - dat += "Logged in to: Central Command Quantum Entanglement Network

" - - if(copyitem) - dat += "Remove Item

" - - if(sendcooldown) - dat += "Transmitter arrays realigning. Please stand by.
" - - else - - dat += "Send
" - dat += "Currently sending: [copyitem.name]
" - dat += "Sending to: [destination]
" - - else - if(sendcooldown) - dat += "Please insert paper to send via secure connection.

" - dat += "Transmitter arrays realigning. Please stand by.
" - else - dat += "Please insert paper to send via secure connection.

" - + data["network"] = "ERR*?*%!*" + if(copyitem) + data["paper"] = copyitem.name + data["paperinserted"] = 1 else - dat += "Proper authentication is required to use this device.

" + data["paper"] = "-----" + data["paperinserted"] = 0 + data["destination"] = destination + data["cooldown"] = sendcooldown + if((destination in admin_departments) || (destination in hidden_admin_departments)) + data["respectcooldown"] = 1 + else + data["respectcooldown"] = 0 - if(copyitem) - dat += "Remove Item
" - - user << browse(dat, "window=copier") - onclose(user, "copier") - return + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "faxmachine.tmpl", "Fax Machine UI", 540, 450) + ui.set_initial_data(data) + ui.open() /obj/machinery/photocopier/faxmachine/Topic(href, href_list) + if(..()) + return 1 + if(href_list["send"]) - if(copyitem) - if (destination in admin_departments) + if(copyitem && authenticated) + if ((destination in admin_departments) || (destination in hidden_admin_departments)) send_admin_fax(usr, destination) else - sendfax(destination) - + sendfax(destination,usr) + if (sendcooldown) spawn(sendcooldown) // cooldown time sendcooldown = 0 + nanomanager.update_uis(src) - else if(href_list["remove"]) + if(href_list["paper"]) if(copyitem) copyitem.loc = usr.loc usr.put_in_hands(copyitem) usr << "You take \the [copyitem] out of \the [src]." copyitem = null - updateUsrDialog() + else + var/obj/item/I = usr.get_active_hand() + if (istype(I, /obj/item/weapon/paper) || istype(I, /obj/item/weapon/photo) || istype(I, /obj/item/weapon/paper_bundle)) + usr.drop_item() + copyitem = I + I.loc = src + usr << "You insert \the [I] into \the [src]." + flick(insert_anim, src) if(href_list["scan"]) - if (scan) - if(ishuman(usr)) - scan.loc = usr.loc - if(!usr.get_active_hand()) - usr.put_in_hands(scan) - scan = null - else - scan.loc = src.loc - scan = null + scan() + + if(href_list["dept"]) + if(authenticated) + var/lastdestination = destination + var/list/combineddepartments = alldepartments + admin_departments + if(emagged) + combineddepartments += hidden_admin_departments + destination = input(usr, "To which department?", "Choose a department", "") as null|anything in combineddepartments + if(!destination) + destination = lastdestination + + if(href_list["auth"]) + if((!authenticated) && scan) + if(check_access(scan)) + authenticated = 1 + else if(authenticated) + authenticated = 0 + + if(href_list["rename"]) + if(copyitem) + var/n_name = sanitize(copytext(input(usr, "What would you like to label the fax?", "Fax Labelling", copyitem.name) as text, 1, MAX_MESSAGE_LEN)) + if((copyitem && copyitem.loc == src && usr.stat == 0)) + if (istype(copyitem, /obj/item/weapon/paper)) + copyitem.name = "[(n_name ? text("[n_name]") : initial(copyitem.name))]" + copyitem.desc = "This is a paper titled '" + copyitem.name + "'." + else if(istype(copyitem, /obj/item/weapon/photo)) + copyitem.name = "[(n_name ? text("[n_name]") : "photo")]" + else if(istype(copyitem, /obj/item/weapon/paper_bundle)) + copyitem.name = "[(n_name ? text("[n_name]") : "paper")]" + + nanomanager.update_uis(src) + +/obj/machinery/photocopier/faxmachine/proc/scan(var/obj/item/weapon/card/id/card = null) + if(scan) // Card is in machine + if(ishuman(usr)) + scan.loc = usr.loc + if(!usr.get_active_hand()) + usr.put_in_hands(scan) + scan = null else + scan.loc = src.loc + scan = null + else + if(!card) var/obj/item/I = usr.get_active_hand() if (istype(I, /obj/item/weapon/card/id)) usr.drop_item() I.loc = src scan = I - authenticated = 0 + else + if(istype(card)) + usr.drop_item() + card.loc = src + scan = card + nanomanager.update_uis(src) - if(href_list["dept"]) - var/lastdestination = destination - destination = input(usr, "Which department?", "Choose a department", "") as null|anything in (alldepartments + admin_departments) - if(!destination) destination = lastdestination - - if(href_list["auth"]) - if ( (!( authenticated ) && (scan)) ) - if (check_access(scan)) - authenticated = 1 - - if(href_list["logout"]) - authenticated = 0 - - updateUsrDialog() - -/obj/machinery/photocopier/faxmachine/proc/sendfax(var/destination) +/obj/machinery/photocopier/faxmachine/proc/sendfax(var/destination,var/mob/sender) if(stat & (BROKEN|NOPOWER)) return - + use_power(200) - + var/success = 0 for(var/obj/machinery/photocopier/faxmachine/F in allfaxes) if( F.department == destination ) - success = F.recievefax(copyitem) - + success = F.receivefax(copyitem) + if (success) + var/datum/fax/F = new /datum/fax() + F.name = copyitem.name + F.from_department = department + F.to_department = destination + F.origin = src + F.message = copyitem + F.sent_by = sender + F.sent_at = world.time + visible_message("[src] beeps, \"Message transmitted successfully.\"") //sendcooldown = 600 else visible_message("[src] beeps, \"Error transmitting message.\"") -/obj/machinery/photocopier/faxmachine/proc/recievefax(var/obj/item/incoming) +/obj/machinery/photocopier/faxmachine/proc/receivefax(var/obj/item/incoming) if(stat & (BROKEN|NOPOWER)) return 0 - + if(department == "Unknown") return 0 //You can't send faxes to "Unknown" flick("faxreceive", src) playsound(loc, "sound/items/polaroid1.ogg", 50, 1) - + // give the sprite some time to flick sleep(20) - + if (istype(incoming, /obj/item/weapon/paper)) copy(incoming) else if (istype(incoming, /obj/item/weapon/photo)) @@ -180,7 +223,7 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins /obj/machinery/photocopier/faxmachine/proc/send_admin_fax(var/mob/sender, var/destination) if(stat & (BROKEN|NOPOWER)) return - + use_power(200) var/obj/item/rcvdcopy @@ -193,23 +236,32 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins else visible_message("[src] beeps, \"Error transmitting message.\"") return - + rcvdcopy.loc = null //hopefully this shouldn't cause trouble - adminfaxes += rcvdcopy - + + var/datum/fax/admin/A = new /datum/fax/admin() + A.name = rcvdcopy.name + A.from_department = department + A.to_department = destination + A.origin = src + A.message = rcvdcopy + A.sent_by = sender + A.sent_at = world.time + //message badmins that a fax has arrived switch(destination) if ("Central Command") - message_admins(sender, "CENTCOMM FAX", rcvdcopy, "CentcommFaxReply", "#006100") - + message_admins(sender, "CENTCOM FAX", destination, rcvdcopy, "#006100") + if ("Syndicate") + message_admins(sender, "SYNDICATE FAX", destination, rcvdcopy, "#DC143C") sendcooldown = 1800 sleep(50) visible_message("[src] beeps, \"Message transmitted successfully.\"") - -/obj/machinery/photocopier/faxmachine/proc/message_admins(var/mob/sender, var/faxname, var/obj/item/sent, var/reply_type, font_colour="#006100") - var/msg = "\blue [faxname]: [key_name(sender, 1)] (PP) (VV) (SM) (JMP) (CA) (REPLY): Receiving '[sent.name]' via secure connection ... view message" + +/obj/machinery/photocopier/faxmachine/proc/message_admins(var/mob/sender, var/faxname, var/faxtype, var/obj/item/sent, font_colour="#006100") + var/msg = "\blue [faxname]: [key_name(sender, 1)] (PP) (VV) (SM) (JMP) (CA) (BSA) (REPLY): Receiving '[sent.name]' via secure connection... view message" for(var/client/C in admins) - if(R_ADMIN & C.holder.rights) + if(R_EVENT & C.holder.rights) C << msg diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index 613b3a39b5f..e520aa1976e 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -33,7 +33,7 @@ I.loc = src -/obj/structure/filingcabinet/attackby(obj/item/P as obj, mob/user as mob) +/obj/structure/filingcabinet/attackby(obj/item/P as obj, mob/user as mob, params) if(istype(P, /obj/item/weapon/paper) || istype(P, /obj/item/weapon/folder) || istype(P, /obj/item/weapon/photo) || istype(P, /obj/item/weapon/paper_bundle) || istype(P, /obj/item/documents)) user << "You put [P] in [src]." user.drop_item() diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm index 828c9f90d29..161ad5065dd 100644 --- a/code/modules/paperwork/folders.dm +++ b/code/modules/paperwork/folders.dm @@ -30,14 +30,14 @@ overlays += "folder_paper" return -/obj/item/weapon/folder/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/folder/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/paper) || istype(W, /obj/item/weapon/photo) || istype(W, /obj/item/weapon/paper_bundle) || istype(W, /obj/item/documents)) user.drop_item() W.loc = src user << "You put the [W] into \the [src]." update_icon() else if(istype(W, /obj/item/weapon/pen)) - var/n_name = copytext(sanitize(input(usr, "What would you like to label the folder?", "Folder Labelling", null) as text), 1, MAX_NAME_LEN) + var/n_name = sanitize(copytext(input(usr, "What would you like to label the folder?", "Folder Labelling", null) as text, 1, MAX_NAME_LEN)) if((loc == usr && usr.stat == 0)) name = "folder[(n_name ? text("- '[n_name]'") : null)]" return diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 976d8da1ca6..374b86eea8d 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -39,20 +39,10 @@ ..() pixel_y = rand(-8, 8) pixel_x = rand(-9, 9) - stamps = "" - - if(name != "paper") - desc = "This is a paper titled '" + name + "'." - - if(info != initial(info)) - info = html_encode(info) - info = replacetext(info, "\n", "
") - info = parsepencode(info) spawn(2) update_icon() updateinfolinks() - return /obj/item/weapon/paper/update_icon() if(icon_state == "paper_talisman") @@ -83,10 +73,10 @@ set category = "Object" set src in usr - if((M_CLUMSY in usr.mutations) && prob(50)) + if((CLUMSY in usr.mutations) && prob(50)) usr << "You cut yourself on the paper." return - var/n_name = copytext(sanitize(input(usr, "What would you like to label the paper?", "Paper Labelling", null) as text), 1, MAX_MESSAGE_LEN) + var/n_name = sanitize(copytext(input(usr, "What would you like to label the paper?", "Paper Labelling", name) as text, 1, MAX_MESSAGE_LEN)) if((loc == usr && usr.stat == 0)) name = "[(n_name ? text("[n_name]") : initial(name))]" if(name != "paper") @@ -195,7 +185,7 @@ /obj/item/weapon/paper/proc/parsepencode(var/t, var/obj/item/weapon/pen/P, mob/user as mob, var/iscrayon = 0) -// t = copytext(sanitize(t),1,MAX_MESSAGE_LEN) +// t = sanitize(copytext(t),1,MAX_MESSAGE_LEN) t = replacetext(t, "\[center\]", "
") t = replacetext(t, "\[/center\]", "
") @@ -303,7 +293,7 @@ "[class]You burn right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.") if(user.get_inactive_hand() == src) - user.drop_from_inventory(src) + user.unEquip(src) new /obj/effect/decal/cleanable/ash(get_turf(src)) del(src) @@ -358,7 +348,7 @@ update_icon() -/obj/item/weapon/paper/attackby(obj/item/weapon/P as obj, mob/user as mob) +/obj/item/weapon/paper/attackby(obj/item/weapon/P as obj, mob/user as mob, params) ..() var/clown = 0 if(user.mind && (user.mind.assigned_role == "Clown")) @@ -376,29 +366,29 @@ B.name = name else if (P.name != "paper" && P.name != "photo") B.name = P.name - user.drop_from_inventory(P) + user.unEquip(P) if (istype(user, /mob/living/carbon/human)) var/mob/living/carbon/human/h_user = user if (h_user.r_hand == src) - h_user.drop_from_inventory(src) + h_user.unEquip(src) h_user.put_in_r_hand(B) else if (h_user.l_hand == src) - h_user.drop_from_inventory(src) + h_user.unEquip(src) h_user.put_in_l_hand(B) else if (h_user.l_store == src) - h_user.drop_from_inventory(src) + h_user.unEquip(src) B.loc = h_user B.layer = 20 h_user.l_store = B h_user.update_inv_pockets() else if (h_user.r_store == src) - h_user.drop_from_inventory(src) + h_user.unEquip(src) B.loc = h_user B.layer = 20 h_user.r_store = B h_user.update_inv_pockets() else if (h_user.head == src) - h_user.u_equip(src) + h_user.unEquip(src) h_user.put_in_hands(B) else if (!istype(src.loc, /turf)) src.loc = get_turf(h_user) @@ -563,7 +553,7 @@ /obj/item/weapon/paper/armory name = "paper- 'Armory Inventory'" - info = "4 Deployable Barriers
4 Portable Flashers
1 Mechanical Toolbox
2 Boxes of Spare Handcuffs
1 Box of Flashbangs
1 Box of Spare R.O.B.U.S.T. Cartridges
1 Tracking Implant Kit
1 Chemical Implant Kit
1 Box of Tear Gas Grenades
1 Explosive Ordnance Disposal Suit
1 Biohazard Suit
3 Gas Masks
1 Lockbox of Loyalty Implants
1 Ion Rifle
3 Sets of Riot Equipment
2 Sets of Security Hardsuits
1 Ablative Armor Vest
3 Bulletproof Vests
3 Helmets

2 Riot Shotguns
2 Boxes of Beanbag Shells
3 Laser Guns
3 Energy Guns
3 Advanced Tasers" + info = "4 Deployable Barriers
4 Portable Flashers
1 Mechanical Toolbox
2 Boxes of Spare Handcuffs
1 Box of Flashbangs
1 Box of Spare R.O.B.U.S.T. Cartridges
1 Tracking Implant Kit
1 Chemical Implant Kit
1 Box of Tear Gas Grenades
1 Explosive Ordnance Disposal Suit
1 Biohazard Suit
6 Gas Masks
1 Lockbox of Loyalty Implants
1 Ion Rifle
3 Sets of Riot Equipment
2 Sets of Security Hardsuits
1 Ablative Armor Vest
3 Bulletproof Vests
3 Helmets

2 Riot Shotguns
2 Boxes of Beanbag Shells
3 Laser Guns
3 Energy Guns
3 Advanced Tasers" /obj/item/weapon/paper/firingrange name = "paper- 'Firing Range Instructions'" diff --git a/code/modules/paperwork/paper_bundle.dm b/code/modules/paperwork/paper_bundle.dm index c3ddfb3cbbb..903fbe84b9a 100644 --- a/code/modules/paperwork/paper_bundle.dm +++ b/code/modules/paperwork/paper_bundle.dm @@ -16,7 +16,7 @@ var/screen = 0 -/obj/item/weapon/paper_bundle/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/paper_bundle/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() var/obj/item/weapon/paper/P if(istype(W, /obj/item/weapon/paper)) @@ -32,7 +32,7 @@ if(screen == 2) screen = 1 user << "You add [(P.name == "paper") ? "the paper" : P.name] to [(src.name == "paper bundle") ? "the paper bundle" : src.name]." - user.drop_from_inventory(P) + user.unEquip(P) P.loc = src if(istype(user,/mob/living/carbon/human)) user:update_inv_l_hand() @@ -42,12 +42,12 @@ if(screen == 2) screen = 1 user << "You add [(W.name == "photo") ? "the photo" : W.name] to [(src.name == "paper bundle") ? "the paper bundle" : src.name]." - user.drop_from_inventory(W) + user.unEquip(W) W.loc = src else if(istype(W, /obj/item/weapon/lighter)) burnpaper(W, user) else if(istype(W, /obj/item/weapon/paper_bundle)) - user.drop_from_inventory(W) + user.unEquip(W) for(var/obj/O in W) O.loc = src O.add_fingerprint(usr) @@ -60,7 +60,7 @@ if(istype(W, /obj/item/weapon/pen) || istype(W, /obj/item/toy/crayon)) usr << browse("", "window=[name]") //Closes the dialog P = src[page] - P.attackby(W, user) + P.attackby(W, user, params) update_icon() @@ -85,7 +85,7 @@ "[class]You burn right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.") if(user.get_inactive_hand() == src) - user.drop_from_inventory(src) + user.unEquip(src) new /obj/effect/decal/cleanable/ash(get_turf(src)) del(src) @@ -166,7 +166,7 @@ usr << "You remove the [W.name] from the bundle." if(amount == 1) var/obj/item/weapon/paper/P = src[1] - usr.drop_from_inventory(src) + usr.unEquip(src) usr.put_in_hands(P) del(src) else if(page == amount) @@ -189,9 +189,9 @@ set category = "Object" set src in usr - var/n_name = copytext(sanitize(input(usr, "What would you like to label the bundle?", "Bundle Labelling", null) as text), 1, MAX_MESSAGE_LEN) + var/n_name = sanitize(copytext(input(usr, "What would you like to label the bundle?", "Bundle Labelling", name) as text, 1, MAX_MESSAGE_LEN)) if((loc == usr && usr.stat == 0)) - name = "[(n_name ? text("[n_name]") : "paper")]" + name = "[(n_name ? text("[n_name]") : "paper bundle")]" add_fingerprint(usr) return @@ -206,7 +206,7 @@ O.loc = usr.loc O.layer = initial(O.layer) O.add_fingerprint(usr) - usr.drop_from_inventory(src) + usr.unEquip(src) del(src) return diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm index 7ee5d21beb2..6eb42ae005d 100644 --- a/code/modules/paperwork/paperbin.dm +++ b/code/modules/paperwork/paperbin.dm @@ -25,15 +25,26 @@ amount=0 update_icon() -/obj/item/weapon/paper_bin/MouseDrop(mob/user as mob) - if((user == usr && (!( usr.restrained() ) && (!( usr.stat ) && (usr.contents.Find(src) || in_range(src, usr)))))) - if(!istype(usr, /mob/living/carbon/slime) && !istype(usr, /mob/living/simple_animal)) - if( !usr.get_active_hand() ) //if active hand is empty - src.loc = user - user.put_in_hands(src) - user.visible_message("[user] picks up the [src].", "You grab [src] from the floor!") - - return +/obj/item/weapon/paper_bin/MouseDrop(atom/over_object) + var/mob/M = usr + if(M.restrained() || M.stat || !Adjacent(M)) + return + + if(over_object == M) + M.put_in_hands(src) + + else if(istype(over_object, /obj/screen)) + switch(over_object.name) + if("r_hand") + if(!M.unEquip(src)) + return + M.put_in_r_hand(src) + if("l_hand") + if(!M.unEquip(src)) + return + M.put_in_l_hand(src) + + add_fingerprint(M) /obj/item/weapon/paper_bin/attack_paw(mob/user as mob) @@ -75,7 +86,7 @@ return -/obj/item/weapon/paper_bin/attackby(obj/item/weapon/paper/i as obj, mob/user as mob) +/obj/item/weapon/paper_bin/attackby(obj/item/weapon/paper/i as obj, mob/user as mob, params) if(!istype(i)) return diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index fb8ba283901..6a6ffdc2d55 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -15,12 +15,11 @@ icon = 'icons/obj/bureaucracy.dmi' icon_state = "pen" item_state = "pen" - flags = FPRINT | TABLEPASS slot_flags = SLOT_BELT | SLOT_EARS throwforce = 0 w_class = 1.0 - throw_speed = 7 - throw_range = 15 + throw_speed = 3 + throw_range = 7 m_amt = 10 var/colour = "black" //what colour the ink is! pressure_resistance = 2 @@ -42,72 +41,37 @@ colour = "white" -/obj/item/weapon/pen/attack(mob/M as mob, mob/user as mob) - if(!ismob(M)) +/obj/item/weapon/pen/attack(mob/living/M, mob/user) + if(!istype(M)) return - user << "You stab [M] with the pen." -// M << "\red You feel a tiny prick!" //That's a whole lot of meta! - M.attack_log += text("\[[time_stamp()]\] Has been stabbed with [name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [name] to stab [M.name] ([M.ckey])") - if(!iscarbon(user)) - M.LAssailant = null - else - M.LAssailant = user - return + if(M.can_inject(user, 1)) + user << "You stab [M] with the pen." +// M << "You feel a tiny prick!" + . = 1 + + add_logs(user, M, "stabbed", object="[name]") /* - * Sleepy Pens + * Sleepypens */ -/obj/item/weapon/pen/sleepypen - desc = "It's a black ink pen with a sharp point and a carefully engraved \"Waffle Co.\"" - flags = FPRINT | TABLEPASS | OPENCONTAINER +/obj/item/weapon/pen/sleepy + flags = OPENCONTAINER origin_tech = "materials=2;syndicate=5" -/obj/item/weapon/pen/sleepypen/New() - var/datum/reagents/R = new/datum/reagents(30) //Used to be 300 - reagents = R - R.my_atom = src - R.add_reagent("chloralhydrate", 22) //Used to be 100 sleep toxin//30 Chloral seems to be fatal, reducing it to 22./N +/obj/item/weapon/pen/sleepy/attack(mob/living/M, mob/user) + if(!istype(M)) return + + if(..()) + if(reagents.total_volume) + if(M.reagents) + reagents.trans_to(M, 55) + + +/obj/item/weapon/pen/sleepy/New() + create_reagents(55) + reagents.add_reagent("stoxin", 30) + reagents.add_reagent("mutetoxin", 15) + reagents.add_reagent("tirizene", 10) ..() - return - - -/obj/item/weapon/pen/sleepypen/attack(mob/M as mob, mob/user as mob) - if(!ismob(M)) - return - ..() - msg_admin_attack("[user.name] ([user.ckey]) Used the [name] to stab [M.name] ([M.ckey]) (JMP)") - if(reagents.total_volume) - if(M.reagents) reagents.trans_to(M, 50) //used to be 150 - return - - -/* - * Parapens - */ -/obj/item/weapon/pen/paralysis - flags = FPRINT | TABLEPASS | OPENCONTAINER - origin_tech = "materials=2;syndicate=5" - - -/obj/item/weapon/pen/paralysis/New() - var/datum/reagents/R = new/datum/reagents(55) - reagents = R - R.my_atom = src - R.add_reagent("stoxin", 30) - R.add_reagent("mutetoxin", 15) - R.add_reagent("tirizene", 10) - ..() - return - - -/obj/item/weapon/pen/paralysis/attack(mob/M as mob, mob/user as mob) - if(!ismob(M)) - return - ..() - msg_admin_attack("[user.name] ([user.ckey]) Used the [name] to stab [M.name] ([M.ckey]) (JMP)") - if(reagents.total_volume) - if(M.reagents) reagents.trans_to(M, 55) //used to be 150 - return \ No newline at end of file diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 2ca5834f56b..da213c0ba76 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -102,7 +102,7 @@ sleep(15) updateUsrDialog() -/obj/machinery/photocopier/attackby(obj/item/O as obj, mob/user as mob) +/obj/machinery/photocopier/attackby(obj/item/O as obj, mob/user as mob, params) if(istype(O, /obj/item/weapon/paper) || istype(O, /obj/item/weapon/photo) || istype(O, /obj/item/weapon/paper_bundle)) if(!copyitem) user.drop_item() diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index 7829a112b0e..412d132a9ff 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -35,7 +35,7 @@ /obj/item/weapon/photo/attack_self(mob/user as mob) src.examine(user) -/obj/item/weapon/photo/attackby(obj/item/weapon/P as obj, mob/user as mob) +/obj/item/weapon/photo/attackby(obj/item/weapon/P as obj, mob/user as mob, params) if(istype(P, /obj/item/weapon/pen) || istype(P, /obj/item/toy/crayon)) var/txt = sanitize(input(user, "What would you like to write on the back?", "Photo Writing", null) as text) txt = copytext(txt, 1, 128) @@ -44,7 +44,7 @@ else if(istype(P, /obj/item/weapon/lighter)) burnphoto(P, user) ..() - + /obj/item/weapon/photo/proc/burnphoto(obj/item/weapon/lighter/P, mob/user) var/class = "" @@ -61,7 +61,7 @@ "[class]You burn right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.") if(user.get_inactive_hand() == src) - user.drop_from_inventory(src) + user.unEquip(src) new /obj/effect/decal/cleanable/ash(get_turf(src)) del(src) @@ -90,7 +90,7 @@ set category = "Object" set src in usr - var/n_name = copytext(sanitize(input(usr, "What would you like to label the photo?", "Photo Labelling", null) as text), 1, MAX_MESSAGE_LEN) + var/n_name = sanitize(copytext(input(usr, "What would you like to label the photo?", "Photo Labelling", name) as text, 1, MAX_MESSAGE_LEN)) //loc.loc check is for making possible renaming photos in clipboards if(( (loc == usr || (loc.loc && loc.loc == usr)) && usr.stat == 0)) name = "[(n_name ? text("[n_name]") : "photo")]" @@ -118,10 +118,10 @@ if((!( M.restrained() ) && !( M.stat ) && M.back == src)) switch(over_object.name) if("r_hand") - M.u_equip(src) + M.unEquip(src) M.put_in_r_hand(src) if("l_hand") - M.u_equip(src) + M.unEquip(src) M.put_in_l_hand(src) add_fingerprint(usr) return @@ -142,7 +142,6 @@ icon_state = "camera" item_state = "electropack" w_class = 2.0 - flags = FPRINT | CONDUCT | TABLEPASS slot_flags = SLOT_BELT var/list/matter = list("metal" = 2000) var/pictures_max = 10 @@ -172,7 +171,7 @@ user << "You switch the camera [on ? "on" : "off"]." return -/obj/item/device/camera/attackby(obj/item/I as obj, mob/user as mob) +/obj/item/device/camera/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/device/camera_film)) if(pictures_left) user << "[src] still has some film in it!" @@ -312,6 +311,7 @@ var/datum/picture/P = new() P.fields["name"] = "photo" + P.fields["author"] = user P.fields["icon"] = ic P.fields["tiny"] = pc P.fields["img"] = photoimage @@ -363,7 +363,6 @@ icon_state = "videocam" item_state = "videocam" w_class = 2.0 - flags = FPRINT | CONDUCT | TABLEPASS slot_flags = SLOT_BELT m_amt = 2000 var/on = 0 @@ -403,4 +402,4 @@ if(get_dist(src, M) <= canhear_range) talk_into(M, msg) for(var/mob/living/carbon/human/H in watcherslist) - H.show_message(text("\blue (Newscaster) [] says, '[]'",M,msg), 1) \ No newline at end of file + H.show_message(text("\blue (Newscaster) [] says, '[]'",M,msg), 1) diff --git a/code/modules/paperwork/stamps.dm b/code/modules/paperwork/stamps.dm index c60489d5669..243762eefb6 100644 --- a/code/modules/paperwork/stamps.dm +++ b/code/modules/paperwork/stamps.dm @@ -1,10 +1,9 @@ /obj/item/weapon/stamp - name = "\improper GRANTED rubber stamp" + name = "\improper rubber stamp" desc = "A rubber stamp for stamping important documents." icon = 'icons/obj/bureaucracy.dmi' icon_state = "stamp-ok" item_state = "stamp" - flags = FPRINT | TABLEPASS throwforce = 0 w_class = 1.0 throw_speed = 7 @@ -54,6 +53,11 @@ icon_state = "stamp-cmo" _color = "cmo" +/obj/item/weapon/stamp/granted + name = "\improper GRANTED rubber stamp" + icon_state = "stamp-ok" + _color = "qm" + /obj/item/weapon/stamp/denied name = "\improper DENIED rubber stamp" icon_state = "stamp-deny" diff --git a/code/modules/power/antimatter/control.dm b/code/modules/power/antimatter/control.dm index 806434fb6df..2bd10af8f20 100644 --- a/code/modules/power/antimatter/control.dm +++ b/code/modules/power/antimatter/control.dm @@ -145,7 +145,7 @@ //No other icons for it atm -/obj/machinery/power/am_control_unit/attackby(obj/item/W, mob/user) +/obj/machinery/power/am_control_unit/attackby(obj/item/W, mob/user, params) if(!istype(W) || !user) return if(istype(W, /obj/item/weapon/wrench)) if(!anchored) @@ -174,7 +174,7 @@ W.loc = src if(user.client) user.client.screen -= W - user.u_equip(W) + user.unEquip(W) user.update_icons() user.visible_message("[user.name] loads an [W.name] into the [src.name].", \ "You load an [W.name].", \ diff --git a/code/modules/power/antimatter/engine.dm b/code/modules/power/antimatter/engine.dm index 77512fb5b0b..3a0967646a8 100644 --- a/code/modules/power/antimatter/engine.dm +++ b/code/modules/power/antimatter/engine.dm @@ -37,7 +37,7 @@ return -/obj/machinery/power/am_engine/injector/attackby(obj/item/weapon/fuel/F, mob/user) +/obj/machinery/power/am_engine/injector/attackby(obj/item/weapon/fuel/F, mob/user, params) if( (stat & BROKEN) || !connected) return if(istype(F, /obj/item/weapon/fuel/H)) diff --git a/code/modules/power/antimatter/fuel.dm b/code/modules/power/antimatter/fuel.dm index f4250bf9378..b81bc1ff13a 100644 --- a/code/modules/power/antimatter/fuel.dm +++ b/code/modules/power/antimatter/fuel.dm @@ -20,7 +20,7 @@ content = "Anti-Hydrogen" fuel = 1e-12 //pico-kilogram -/obj/item/weapon/fuel/attackby(obj/item/weapon/fuel/F, mob/user) +/obj/item/weapon/fuel/attackby(obj/item/weapon/fuel/F, mob/user, params) ..() if(istype(src, /obj/item/weapon/fuel/antiH)) if(istype(F, /obj/item/weapon/fuel/antiH)) diff --git a/code/modules/power/antimatter/shielding.dm b/code/modules/power/antimatter/shielding.dm index ae96a8f9f46..736237ad55c 100644 --- a/code/modules/power/antimatter/shielding.dm +++ b/code/modules/power/antimatter/shielding.dm @@ -135,7 +135,7 @@ proc/cardinalrange(var/center) else if(processing) shutdown_core() -/obj/machinery/am_shielding/attackby(obj/item/W, mob/user) +/obj/machinery/am_shielding/attackby(obj/item/W, mob/user, params) if(!istype(W) || !user) return if(W.force > 10) stability -= W.force/2 @@ -206,14 +206,14 @@ proc/cardinalrange(var/center) icon_state = "box" item_state = "electronic" w_class = 4.0 - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT throwforce = 5 throw_speed = 1 throw_range = 2 m_amt = 100 w_amt = 2000 -/obj/item/device/am_shielding_container/attackby(var/obj/item/I, var/mob/user) +/obj/item/device/am_shielding_container/attackby(var/obj/item/I, var/mob/user, params) if(istype(I, /obj/item/device/multitool) && istype(src.loc,/turf)) new/obj/machinery/am_shielding(src.loc) del(src) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 9697509e5e1..d0cf07fc9e1 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -52,7 +52,7 @@ var/spooky=0 var/area/area var/areastring = null - var/obj/item/weapon/cell/cell + var/obj/item/weapon/stock_parts/cell/cell var/start_charge = 90 // initial cell charge % var/cell_type = 2500 // 0=no cell, 1=regular, 2=high-cap (x5) <- old, now it's just 0=no cell, otherwise dictate cellcapacity by changing this value. 1 used to be 1000, 2 was 2500 var/opened = 0 //0=closed, 1=opened, 2=cover removed @@ -142,7 +142,7 @@ has_electronics = 2 //installed and secured // is starting with a power cell installed, create it and set its charge level if(cell_type) - src.cell = new/obj/item/weapon/cell(src) + src.cell = new/obj/item/weapon/stock_parts/cell(src) cell.maxcharge = cell_type // cell_type is maximum charge (old default was 1000 or 2500 (values one and two respectively) cell.charge = start_charge * cell.maxcharge / 100.0 // (convert percentage to actual value) @@ -365,7 +365,7 @@ //attack with an item - open/close cover, insert cell, or (un)lock interface -/obj/machinery/power/apc/attackby(obj/item/W, mob/user) +/obj/machinery/power/apc/attackby(obj/item/W, mob/living/user, params) if (istype(user, /mob/living/silicon) && get_dist(src,user)>1) return src.attack_hand(user) @@ -399,7 +399,7 @@ else opened = 1 update_icon() - else if (istype(W, /obj/item/weapon/cell) && opened) // trying to put a cell inside + else if (istype(W, /obj/item/weapon/stock_parts/cell) && opened) // trying to put a cell inside if(cell) user << "There is a power cell already installed." return @@ -458,23 +458,6 @@ update_icon() else user << "\red Access denied." - else if (istype(W, /obj/item/weapon/card/emag) && !(emagged || malfhack)) // trying to unlock with an emag card - if(opened) - user << "You must close the cover to swipe an ID card." - else if(wiresexposed) - user << "You must close the panel first" - else if(stat & (BROKEN|MAINT)) - user << "Nothing happens." - else - flick("apc-spark", src) - if (do_after(user,6)) - if(prob(50)) - emagged = 1 - locked = 0 - user << "You emag the APC interface." - update_icon() - else - user << "You fail to [ locked ? "unlock" : "lock"] the APC interface." else if (istype(W, /obj/item/stack/cable_coil) && !terminal && opened && has_electronics!=2) if (src.loc:intact) user << "\red You must remove the floor plating in front of the APC first." @@ -594,12 +577,31 @@ (istype(W, /obj/item/device/multitool) || \ istype(W, /obj/item/weapon/wirecutters) || istype(W, /obj/item/device/assembly/signaler))) return src.attack_hand(user) + user.do_attack_animation(src) user.visible_message("\red The [src.name] has been hit with the [W.name] by [user.name]!", \ "\red You hit the [src.name] with your [W.name]!", \ "You hear bang") +/obj/machinery/power/apc/emag_act(user as mob) + if (!(emagged || malfhack)) // trying to unlock with an emag card + if(opened) + user << "You must close the cover to swipe an ID card." + else if(wiresexposed) + user << "You must close the panel first" + else if(stat & (BROKEN|MAINT)) + user << "Nothing happens." + else + flick("apc-spark", src) + if (do_after(user,6)) + if(prob(50)) + emagged = 1 + locked = 0 + user << "You emag the APC interface." + update_icon() + else + user << "You fail to [ locked ? "unlock" : "lock"] the APC interface." + // attack with hand - remove cell (if cover open) or interact with the APC - /obj/machinery/power/apc/attack_hand(mob/user) // if (!can_use(user)) This already gets called in interact() and in topic() // return @@ -670,6 +672,8 @@ return if(indestructible) return + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) user.visible_message("\red [user.name] slashes at the [src.name]!", "\blue You slash at the [src.name]!") playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1) @@ -687,8 +691,12 @@ else beenhit += 1 return - - + +/obj/machinery/power/apc/attack_ghost(user as mob) + if(stat & (BROKEN|MAINT)) + return + return ui_interact(user) + /obj/machinery/power/apc/interact(mob/user) if(!user) return @@ -805,6 +813,8 @@ if (user.stat && !isobserver(user)) user << "\red You must be conscious to use this [src]!" return 0 + if(stat & (NOPOWER|BROKEN)) + return 0 if(!user.client) return 0 if ( ! (istype(user, /mob/living/carbon/human) || \ @@ -849,36 +859,63 @@ user << "\red You momentarily forget how to use [src]." return 0 return 1 + +/obj/machinery/power/apc/proc/is_authenticated(mob/user as mob) + if(isAI(user) || isrobot(user)) + return 1 + else + return !locked /obj/machinery/power/apc/Topic(href, href_list, var/usingUI = 1) + if(..()) + return 1 + if(!can_use(usr, 1)) - return 0 + return 1 if (href_list["lock"]) + if(!is_authenticated(usr)) + return + coverlocked = !coverlocked else if (href_list["breaker"]) + if(!is_authenticated(usr)) + return + toggle_breaker() else if (href_list["cmode"]) + if(!is_authenticated(usr)) + return + chargemode = !chargemode if(!chargemode) charging = 0 update_icon() else if (href_list["eqp"]) + if(!is_authenticated(usr)) + return + var/val = text2num(href_list["eqp"]) equipment = setsubsystem(val) update_icon() update() else if (href_list["lgt"]) + if(!is_authenticated(usr)) + return + var/val = text2num(href_list["lgt"]) lighting = setsubsystem(val) update_icon() update() else if (href_list["env"]) + if(!is_authenticated(usr)) + return + var/val = text2num(href_list["env"]) environ = setsubsystem(val) update_icon() @@ -893,7 +930,7 @@ return 0 else if (href_list["overload"]) - if(istype(usr, /mob/living/silicon)) + if(istype(usr, /mob/living/silicon) && !aidisabled) src.overload_lighting() else if (href_list["malfhack"]) @@ -912,7 +949,7 @@ malfai.malfhacking = 0 locked = 1 if (ticker.mode.config_tag == "malfunction") - if (src.z == 1) //if (is_type_in_list(get_area(src), the_station_areas)) + if ((src.z in config.station_levels)) //if (is_type_in_list(get_area(src), the_station_areas)) ticker.mode:apcs++ if(usr:parent) src.malfai = usr:parent @@ -931,20 +968,20 @@ else if (href_list["toggleaccess"]) if(istype(usr, /mob/living/silicon)) - if(emagged || (stat & (BROKEN|MAINT))) + if(emagged || aidisabled || (stat & (BROKEN|MAINT))) usr << "The APC does not respond to the command." else locked = !locked update_icon() - return 1 + return 0 /obj/machinery/power/apc/proc/toggle_breaker() operating = !operating if(malfai) if (ticker.mode.config_tag == "malfunction") - if (src.z == 1) //if (is_type_in_list(get_area(src), the_station_areas)) + if ((src.z in config.station_levels)) //if (is_type_in_list(get_area(src), the_station_areas)) operating ? ticker.mode:apcs++ : ticker.mode:apcs-- src.update() @@ -959,7 +996,7 @@ if(!malf.can_shunt) malf << "You cannot shunt." return - if(src.z != 1) + if(!(src.z in config.station_levels)) return src.occupant = new /mob/living/silicon/ai(src,malf.laws,null,1) src.occupant.adjustOxyLoss(malf.getOxyLoss()) @@ -1008,7 +1045,7 @@ /obj/machinery/power/apc/proc/ion_act() //intended to be exactly the same as an AI malf attack - if(!src.malfhack && src.z == 1) + if(!src.malfhack && (src.z in config.station_levels)) if(prob(3)) src.locked = 1 if (src.cell.charge > 0) @@ -1277,7 +1314,7 @@ obj/machinery/power/apc/proc/autoset(var/val, var/on) /obj/machinery/power/apc/proc/set_broken() if(malfai && operating) if (ticker.mode.config_tag == "malfunction") - if (src.z == 1) //if (is_type_in_list(get_area(src), the_station_areas)) + if ((src.z in config.station_levels)) //if (is_type_in_list(get_area(src), the_station_areas)) ticker.mode:apcs-- stat |= BROKEN operating = 0 @@ -1303,7 +1340,7 @@ obj/machinery/power/apc/proc/autoset(var/val, var/on) /obj/machinery/power/apc/Destroy() if(malfai && operating) if (ticker.mode.config_tag == "malfunction") - if (src.z == 1) //if (is_type_in_list(get_area(src), the_station_areas)) + if ((src.z in config.station_levels)) //if (is_type_in_list(get_area(src), the_station_areas)) ticker.mode:apcs-- area.power_light = 0 area.power_equip = 0 diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index c688127ad2b..4e3e9410ed1 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -1,6 +1,6 @@ // attach a wire to a power machine - leads from the turf you are standing on -/obj/machinery/power/attackby(obj/item/weapon/W, mob/user) +/obj/machinery/power/attackby(obj/item/weapon/W, mob/user, params) if(istype(W, /obj/item/stack/cable_coil)) @@ -120,7 +120,7 @@ /obj/structure/cable/attack_tk(mob/user) return -/obj/structure/cable/attackby(obj/item/W, mob/user) +/obj/structure/cable/attackby(obj/item/W, mob/user, params) var/turf/T = src.loc if(T.intact) @@ -216,7 +216,7 @@ throw_range = 5 m_amt = 50 g_amt = 20 - flags = TABLEPASS | FPRINT | CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT attack_verb = list("whipped", "lashed", "disciplined", "flogged") @@ -270,7 +270,7 @@ if(src.amount <= 14) usr << "\red You need at least 15 lengths to make restraints!" return - var/obj/item/weapon/handcuffs/cable/B = new /obj/item/weapon/handcuffs/cable(usr.loc) + var/obj/item/weapon/restraints/handcuffs/cable/B = new /obj/item/weapon/restraints/handcuffs/cable(usr.loc) B.icon_state = "cuff_[_color]" usr << "\blue You wind some cable together to make some restraints." src.use(15) @@ -278,7 +278,7 @@ usr << "\blue You cannot do that." ..() -/obj/item/stack/cable_coil/attackby(obj/item/weapon/W, mob/user) +/obj/item/stack/cable_coil/attackby(obj/item/weapon/W, mob/user, params) ..() if( istype(W, /obj/item/weapon/wirecutters) && src.amount > 1) src.amount-- @@ -313,7 +313,7 @@ //handle mob icon update if(ismob(loc)) var/mob/M = loc - M.u_equip(src) + M.unEquip(src) del(src) else amount -= used diff --git a/code/modules/power/cable_heavyduty.dm b/code/modules/power/cable_heavyduty.dm index 36bd4f93eb7..111b5b7ec3d 100644 --- a/code/modules/power/cable_heavyduty.dm +++ b/code/modules/power/cable_heavyduty.dm @@ -9,7 +9,7 @@ desc = "This cable is tough. It cannot be cut with simple hand tools." layer = 2.39 //Just below pipes, which are at 2.4 -/obj/structure/cable/heavyduty/attackby(obj/item/W, mob/user) +/obj/structure/cable/heavyduty/attackby(obj/item/W, mob/user, params) var/turf/T = src.loc if(T.intact) diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index e099b39e35d..a6a35858216 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -1,16 +1,16 @@ // the power cell // charge from 0 to 100% // fits in APC to provide backup power -/obj/item/weapon/cell/var/image/overlay_image +/obj/item/weapon/stock_parts/cell/var/image/overlay_image -/obj/item/weapon/cell/New() +/obj/item/weapon/stock_parts/cell/New() ..() charge = maxcharge spawn(5) updateicon() -/obj/item/weapon/cell/proc/updateicon() +/obj/item/weapon/stock_parts/cell/proc/updateicon() if(isnull(src.overlay_image)) src.overlay_image = image('icons/obj/power.dmi') overlays.Cut() @@ -24,11 +24,11 @@ src.overlay_image.icon_state = "cell-o1" overlays += src.overlay_image -/obj/item/weapon/cell/proc/percent() // return % charge of cell +/obj/item/weapon/stock_parts/cell/proc/percent() // return % charge of cell return 100.0*charge/maxcharge // use power from a cell -/obj/item/weapon/cell/proc/use(var/amount) +/obj/item/weapon/stock_parts/cell/proc/use(var/amount) if(rigged && amount > 0) explode() return 0 @@ -38,7 +38,7 @@ return 1 // recharge the cell -/obj/item/weapon/cell/proc/give(var/amount) +/obj/item/weapon/stock_parts/cell/proc/give(var/amount) if(rigged && amount > 0) explode() return 0 @@ -55,7 +55,7 @@ return power_used -/obj/item/weapon/cell/examine() +/obj/item/weapon/stock_parts/cell/examine() set src in view(1) if(usr /*&& !usr.stat*/) if(maxcharge <= 2500) @@ -65,7 +65,7 @@ if(crit_fail) usr << "\red This power cell seems to be faulty." -/obj/item/weapon/cell/attack_self(mob/user as mob) +/obj/item/weapon/stock_parts/cell/attack_self(mob/user as mob) src.add_fingerprint(user) if(ishuman(user)) @@ -76,7 +76,7 @@ SNG.drain("CELL",src,H.wear_suit) return -/obj/item/weapon/cell/attackby(obj/item/W, mob/user) +/obj/item/weapon/stock_parts/cell/attackby(obj/item/W, mob/user, params) ..() if(istype(W, /obj/item/weapon/reagent_containers/syringe)) var/obj/item/weapon/reagent_containers/syringe/S = W @@ -93,7 +93,7 @@ S.reagents.clear_reagents() -/obj/item/weapon/cell/proc/explode() +/obj/item/weapon/stock_parts/cell/proc/explode() var/turf/T = get_turf(src.loc) /* * 1000-cell explosion(T, -1, 0, 1, 1) @@ -121,13 +121,13 @@ spawn(1) del(src) -/obj/item/weapon/cell/proc/corrupt() +/obj/item/weapon/stock_parts/cell/proc/corrupt() charge /= 2 maxcharge /= 2 if (prob(10)) rigged = 1 //broken batterys are dangerous -/obj/item/weapon/cell/emp_act(severity) +/obj/item/weapon/stock_parts/cell/emp_act(severity) charge -= 1000 / severity if (charge < 0) charge = 0 @@ -135,7 +135,7 @@ reliability -= 10 / severity ..() -/obj/item/weapon/cell/ex_act(severity) +/obj/item/weapon/stock_parts/cell/ex_act(severity) switch(severity) if(1.0) @@ -155,10 +155,10 @@ corrupt() return -/obj/item/weapon/cell/blob_act() +/obj/item/weapon/stock_parts/cell/blob_act() ex_act(1) -/obj/item/weapon/cell/proc/get_electrocute_damage() +/obj/item/weapon/stock_parts/cell/proc/get_electrocute_damage() switch (charge) /* if (9000 to INFINITY) return min(rand(90,150),rand(90,150)) diff --git a/code/modules/power/generator.dm b/code/modules/power/generator.dm index 0acf4a854d4..bd590c766f0 100644 --- a/code/modules/power/generator.dm +++ b/code/modules/power/generator.dm @@ -118,7 +118,7 @@ if(stat & (BROKEN|NOPOWER)) return interact(user) -/obj/machinery/power/generator/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/power/generator/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/wrench)) anchored = !anchored user << "\blue You [anchored ? "secure" : "unsecure"] the bolts holding [src] to the floor." diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm index df04bacdc70..872303d3e91 100644 --- a/code/modules/power/gravitygenerator.dm +++ b/code/modules/power/gravitygenerator.dm @@ -63,8 +63,8 @@ var/const/GRAV_NEEDS_WRENCH = 3 /obj/machinery/gravity_generator/part var/obj/machinery/gravity_generator/main/main_part = null -/obj/machinery/gravity_generator/part/attackby(obj/item/I as obj, mob/user as mob) - return main_part.attackby(I, user) +/obj/machinery/gravity_generator/part/attackby(obj/item/I as obj, mob/user as mob, params) + return main_part.attackby(I, user, params) /obj/machinery/gravity_generator/part/get_status() return main_part.get_status() @@ -123,7 +123,7 @@ var/const/GRAV_NEEDS_WRENCH = 3 O.main_part = null qdel(O) for(var/area/A in world) - if (A.z != 1) continue + if (!(A.z in config.station_levels)) continue A.gravitychange(0,A) shake_everyone() ..() @@ -177,7 +177,7 @@ var/const/GRAV_NEEDS_WRENCH = 3 // Interaction // Fixing the gravity generator. -/obj/machinery/gravity_generator/main/attackby(obj/item/I as obj, mob/user as mob) +/obj/machinery/gravity_generator/main/attackby(obj/item/I as obj, mob/user as mob, params) var/old_broken_state = broken_state switch(broken_state) if(GRAV_NEEDS_SCREWDRIVER) @@ -294,7 +294,7 @@ var/const/GRAV_NEEDS_WRENCH = 3 investigate_log("was brought online and is now producing gravity for this level.", "gravity") message_admins("The gravity generator was brought online. ([area.name])") for(var/area/A in world) - if (A.z != 1) continue + if (!(A.z in config.station_levels)) continue A.gravitychange(1,A) else if(gravity_in_level() == 1) @@ -302,7 +302,7 @@ var/const/GRAV_NEEDS_WRENCH = 3 investigate_log("was brought offline and there is now no gravity for this level.", "gravity") message_admins("The gravity generator was brought offline with no backup generator. ([area.name])") for(var/area/A in world) - if (A.z != 1) continue + if (!(A.z in config.station_levels)) continue A.gravitychange(0,A) update_icon() diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 353ea877b4c..856443396c5 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -16,12 +16,12 @@ desc = "Used for building lights." icon = 'icons/obj/lighting.dmi' icon_state = "tube-construct-item" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT var/fixture_type = "tube" var/obj/machinery/light/newlight = null var/sheets_refunded = 2 -/obj/item/light_fixture_frame/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/light_fixture_frame/attackby(obj/item/weapon/W as obj, mob/living/user as mob, params) if (istype(W, /obj/item/weapon/wrench)) new /obj/item/stack/sheet/metal( get_turf(src.loc), sheets_refunded ) del(src) @@ -63,7 +63,7 @@ desc = "Used for building small lights." icon = 'icons/obj/lighting.dmi' icon_state = "bulb-construct-item" - flags = FPRINT | TABLEPASS| CONDUCT + flags = CONDUCT fixture_type = "bulb" sheets_refunded = 1 @@ -99,7 +99,7 @@ usr << "The casing is closed." return -/obj/machinery/light_construct/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/light_construct/attackby(obj/item/weapon/W as obj, mob/living/user as mob, params) src.add_fingerprint(user) if (istype(W, /obj/item/weapon/wrench)) if (src.stage == 1) @@ -344,7 +344,7 @@ // attack with item - insert light (if right type), otherwise try to break the light -/obj/machinery/light/attackby(obj/item/W, mob/user) +/obj/machinery/light/attackby(obj/item/W, mob/living/user, params) //Light replacer code if(istype(W, /obj/item/device/lightreplacer)) @@ -390,7 +390,7 @@ else if(status != LIGHT_BROKEN && status != LIGHT_EMPTY) - + user.do_attack_animation(src) if(prob(1+W.force * 5)) user << "You hit the light, and it smashes!" @@ -399,13 +399,14 @@ continue M.show_message("[user.name] smashed the light!", 3, "You hear a tinkle of breaking glass", 2) if(on && (W.flags & CONDUCT)) - //if(!user.mutations & M_RESIST_COLD) + //if(!user.mutations & RESIST_COLD) if (prob(12)) electrocute_mob(user, get_area(src), src, 0.3) broken() else - user << "You hit the light!" + user.visible_message("[user.name] hits the light.") + playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1) // attempt to stick weapon into light socket else if(status == LIGHT_EMPTY) @@ -435,7 +436,7 @@ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(3, 1, src) s.start() - //if(!user.mutations & M_RESIST_COLD) + //if(!user.mutations & RESIST_COLD) if (prob(75)) electrocute_mob(user, get_area(src), src, rand(0.7,1.0)) @@ -471,8 +472,8 @@ user << "\green That object is useless to you." return else if (status == LIGHT_OK||status == LIGHT_BURNED) - for(var/mob/M in viewers(src)) - M.show_message("\red [user.name] smashed the light!", 3, "You hear a tinkle of breaking glass", 2) + user.do_attack_animation(src) + visible_message("[user.name] smashed the light!", "You hear a tinkle of breaking glass") broken() return @@ -482,8 +483,8 @@ M << "\red That object is useless to you." return else if (status == LIGHT_OK||status == LIGHT_BURNED) - for(var/mob/O in viewers(src)) - O.show_message("\red [M.name] smashed the light!", 3, "You hear a tinkle of breaking glass", 2) + M.do_attack_animation(src) + visible_message("[M.name] smashed the light!", "You hear a tinkle of breaking glass") broken() return // attack with hand - remove tube/bulb @@ -511,9 +512,9 @@ else prot = 1 - if(prot > 0 || (M_RESIST_HEAT in user.mutations)) + if(prot > 0 || (RESIST_HEAT in user.mutations)) user << "You remove the light [fitting]" - else if(M_TK in user.mutations) + else if(TK in user.mutations) user << "You telekinetically remove the light [fitting]." else user << "You try to remove the light [fitting], but you burn your hand on it!" @@ -657,7 +658,6 @@ /obj/item/weapon/light icon = 'icons/obj/lighting.dmi' - flags = FPRINT | TABLEPASS force = 2 throwforce = 5 w_class = 1 @@ -731,7 +731,7 @@ // attack bulb/tube with object // if a syringe, can inject plasma to make it explode -/obj/item/weapon/light/attackby(var/obj/item/I, var/mob/user) +/obj/item/weapon/light/attackby(var/obj/item/I, var/mob/user, params) ..() if(istype(I, /obj/item/weapon/reagent_containers/syringe)) var/obj/item/weapon/reagent_containers/syringe/S = I diff --git a/code/modules/power/pacman2.dm b/code/modules/power/pacman2.dm index 89d65a6ae21..cddda73be6e 100644 --- a/code/modules/power/pacman2.dm +++ b/code/modules/power/pacman2.dm @@ -35,8 +35,8 @@ component_parts = list() component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) component_parts += new /obj/item/weapon/stock_parts/micro_laser(src) - component_parts += new /obj/item/weapon/cable_coil(src) - component_parts += new /obj/item/weapon/cable_coil(src) + component_parts += new /obj/item/stack/cable_coil(src) + component_parts += new /obj/item/stack/cable_coil(src) component_parts += new /obj/item/weapon/stock_parts/capacitor(src) component_parts += new board_path(src) RefreshParts() @@ -72,7 +72,7 @@ overheat() explosion(get_turf(src), 2, 5, 2, -1) - attackby(var/obj/item/O as obj, var/mob/user as mob) + attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(istype(O, /obj/item/weapon/tank/plasma)) if(P) user << "\red The generator already has a plasma tank loaded!" @@ -81,14 +81,6 @@ user.drop_item() O.loc = src user << "\blue You add the plasma tank to the generator." - else if (istype(O, /obj/item/weapon/card/emag)) - var/obj/item/weapon/card/emag/E = O - if(E.uses) - E.uses-- - else - return - emagged = 1 - emp_act(1) else if(!active) if(istype(O, /obj/item/weapon/wrench)) anchored = !anchored @@ -114,6 +106,11 @@ new_frame.state = 2 new_frame.icon_state = "box_1" del(src) + + emag_act(user as mob) + if(!emagged) + emagged = 1 + emp_act(1) attack_hand(mob/user as mob) ..() diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index a334782cce1..a434098da03 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -26,7 +26,7 @@ /obj/machinery/power/port_gen/process() ideally we're looking to generate 5000 -/obj/machinery/power/port_gen/attackby(obj/item/weapon/W, mob/user) +/obj/machinery/power/port_gen/attackby(obj/item/weapon/W, mob/user, params) tank [un]loading stuff /obj/machinery/power/port_gen/attack_hand(mob/user) @@ -199,7 +199,7 @@ display round(lastgen) and plasmatank amount /obj/machinery/power/port_gen/pacman/proc/overheat() explosion(src.loc, 2, 5, 2, -1) -/obj/machinery/power/port_gen/pacman/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/machinery/power/port_gen/pacman/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(istype(O, sheet_path)) var/obj/item/stack/addstack = O var/amount = min((max_sheets - sheets), addstack.amount) @@ -211,9 +211,6 @@ display round(lastgen) and plasmatank amount addstack.use(amount) updateUsrDialog() return - else if (istype(O, /obj/item/weapon/card/emag)) - emagged = 1 - emp_act(1) else if(!active) if(istype(O, /obj/item/weapon/wrench)) if(!anchored && !isinspace()) @@ -239,6 +236,10 @@ display round(lastgen) and plasmatank amount else if(istype(O, /obj/item/weapon/crowbar) && panel_open) default_deconstruction_crowbar(O) +/obj/machinery/power/port_gen/pacman/emag_act(user as mob) + emagged = 1 + emp_act(1) + /obj/machinery/power/port_gen/pacman/attack_hand(mob/user as mob) ..() if (!anchored) diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index bff319d9b60..fbb8d479470 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -475,11 +475,11 @@ power_source = Cable.powernet var/datum/powernet/PN - var/obj/item/weapon/cell/cell + var/obj/item/weapon/stock_parts/cell/cell if(istype(power_source,/datum/powernet)) PN = power_source - else if(istype(power_source,/obj/item/weapon/cell)) + else if(istype(power_source,/obj/item/weapon/stock_parts/cell)) cell = power_source else if(istype(power_source,/obj/machinery/power/apc)) var/obj/machinery/power/apc/apc = power_source @@ -514,7 +514,7 @@ else if (istype(power_source,/datum/powernet)) var/drained_power = drained_energy/CELLRATE //convert from "joules" to "watts" PN.newload+=drained_power - else if (istype(power_source, /obj/item/weapon/cell)) + else if (istype(power_source, /obj/item/weapon/stock_parts/cell)) cell.use(drained_energy) return drained_energy diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm index 0f1340ac0d8..b59c01d9a23 100644 --- a/code/modules/power/singularity/collector.dm +++ b/code/modules/power/singularity/collector.dm @@ -50,7 +50,7 @@ var/global/list/rad_collectors = list() ..() -/obj/machinery/power/rad_collector/attackby(obj/item/W, mob/user) +/obj/machinery/power/rad_collector/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/device/analyzer)) user << "\blue The [W.name] detects that [last_power]W were recently produced." return 1 diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 4142778e1e3..b198a50bd8f 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -40,7 +40,7 @@ src.directwired = 1 /obj/machinery/power/emitter/Destroy() - message_admins("Emitter deleted at ([x],[y],[z] - JMP)",0,1) + msg_admin_attack("Emitter deleted at ([x],[y],[z] - JMP)",0,1) log_game("Emitter deleted at ([x],[y],[z])") investigate_log("deleted at ([x],[y],[z])","singulo") ..() @@ -144,7 +144,7 @@ A.process() //TODO: Carn: check this out -/obj/machinery/power/emitter/attackby(obj/item/W, mob/user) +/obj/machinery/power/emitter/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/weapon/wrench)) if(active) @@ -222,12 +222,14 @@ user << "\red Access denied." return - - if(istype(W, /obj/item/weapon/card/emag) && !emagged) + ..() + return + +/obj/machinery/power/emitter/emag_act(user as mob) + if(!emagged) + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user locked = 0 emagged = 1 - user.visible_message("[user.name] emags the [src.name].","\red You short out the lock.") - return - - ..() - return \ No newline at end of file + H.visible_message("[H.name] emags the [src.name].","\red You short out the lock.") diff --git a/code/modules/power/singularity/field_generator.dm b/code/modules/power/singularity/field_generator.dm index da470fbee52..851bbe20eb2 100644 --- a/code/modules/power/singularity/field_generator.dm +++ b/code/modules/power/singularity/field_generator.dm @@ -95,7 +95,7 @@ field_generator power level display return -/obj/machinery/field_generator/attackby(obj/item/W, mob/user) +/obj/machinery/field_generator/attackby(obj/item/W, mob/user, params) if(active) user << "The [src] needs to be off." return @@ -350,6 +350,6 @@ field_generator power level display if(O.last_warning && temp) if((world.time - O.last_warning) > 50) //to stop message-spam temp = 0 - message_admins("A singulo exists and a containment field has failed.",1) + msg_admin_attack("A singulo exists and a containment field has failed.",1) investigate_log("has failed whilst a singulo exists.","singulo") O.last_warning = world.time diff --git a/code/modules/power/singularity/generator.dm b/code/modules/power/singularity/generator.dm index bcd8403b54c..1a88f444d24 100644 --- a/code/modules/power/singularity/generator.dm +++ b/code/modules/power/singularity/generator.dm @@ -29,7 +29,7 @@ new /obj/machinery/singularity/(T, 50) if(src) del(src) -/obj/machinery/the_singularitygen/attackby(obj/item/W, mob/user) +/obj/machinery/the_singularitygen/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/weapon/wrench)) anchored = !anchored playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) diff --git a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm index ed441450ca8..b645f7b6b79 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm @@ -120,7 +120,7 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin return -/obj/structure/particle_accelerator/attackby(obj/item/W, mob/user) +/obj/structure/particle_accelerator/attackby(obj/item/W, mob/user, params) if(istool(W)) if(src.process_tool_hit(W,user)) return @@ -314,7 +314,7 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin return -/obj/machinery/particle_accelerator/attackby(obj/item/W, mob/user) +/obj/machinery/particle_accelerator/attackby(obj/item/W, mob/user, params) if(istool(W)) if(src.process_tool_hit(W,user)) return diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index c9726924f43..3af4d2fbf2c 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -1,6 +1,7 @@ //This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33 // Added spess ghoasts/cameras to this so they don't add to the lag. - N3X +var/global/narsie_cometh = 0 var/global/list/uneatable = list( /turf/space, /obj/effect/overlay, @@ -508,6 +509,7 @@ var/global/list/uneatable = list( if(emergency_shuttle && emergency_shuttle.can_call()) emergency_shuttle.call_evac() emergency_shuttle.launch_time = 0 // Cannot recall + narsie_cometh = 1 /obj/machinery/singularity/narsie/proc/spawn_animation() @@ -541,7 +543,7 @@ var/global/list/uneatable = list( if(istype(A,/obj/)) var/obj/O = A O.ex_act(1.0) - if(O) del(O) + if(O) qdel(O) else if(isturf(A)) var/turf/T = A @@ -565,7 +567,7 @@ var/global/list/uneatable = list( var/obj/O = A machines -= O processing_objects -= O - O.loc = null + qdel(O) else if(isturf(A)) var/turf/T = A if(istype(T,/turf/simulated/wall)) diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index 1613bc46187..d7fedfb7a8f 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -33,11 +33,11 @@ ..() component_parts = list() component_parts += new /obj/item/weapon/circuitboard/smes(null) - component_parts += new /obj/item/weapon/cell/high(null) - component_parts += new /obj/item/weapon/cell/high(null) - component_parts += new /obj/item/weapon/cell/high(null) - component_parts += new /obj/item/weapon/cell/high(null) - component_parts += new /obj/item/weapon/cell/high(null) + component_parts += new /obj/item/weapon/stock_parts/cell/high(null) + component_parts += new /obj/item/weapon/stock_parts/cell/high(null) + component_parts += new /obj/item/weapon/stock_parts/cell/high(null) + component_parts += new /obj/item/weapon/stock_parts/cell/high(null) + component_parts += new /obj/item/weapon/stock_parts/cell/high(null) component_parts += new /obj/item/weapon/stock_parts/capacitor(null) component_parts += new /obj/item/stack/cable_coil(null, 5) RefreshParts() @@ -68,7 +68,7 @@ IO += CP.rating input_level_max = 200000 * IO output_level_max = 200000 * IO - for(var/obj/item/weapon/cell/PC in component_parts) + for(var/obj/item/weapon/stock_parts/cell/PC in component_parts) C += PC.maxcharge capacity = C / (15000) * 1e6 @@ -107,7 +107,7 @@ return -/obj/machinery/power/smes/attackby(obj/item/I, mob/user) +/obj/machinery/power/smes/attackby(obj/item/I, mob/user, params) //opening using screwdriver if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), I)) update_icon() @@ -332,6 +332,9 @@ add_fingerprint(user) ui_interact(user) +/obj/machinery/power/smes/attack_ghost(mob/user) + ui_interact(user) + /obj/machinery/power/smes/attack_hand(mob/user) add_fingerprint(user) ui_interact(user) @@ -421,7 +424,7 @@ /obj/machinery/power/smes/proc/ion_act() - if(src.z == 1) + if((src.z in config.station_levels)) if(prob(1)) //explosion world << "\red SMES explosion in [src.loc.loc]" for(var/mob/M in viewers(src)) diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index 9c622e47ca9..7b9df9303b2 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -1,20 +1,8 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33 - #define SOLAR_MAX_DIST 40 #define SOLARGENRATE 1500 var/list/solars_list = list() -// This will choose whether to get the solar list from the powernet or the powernet nodes, -// depending on the size of the nodes. -/obj/machinery/power/proc/get_solars_powernet() - if(!powernet) - return list() - if(solars_list.len < powernet.nodes) - return solars_list - else - return powernet.nodes - /obj/machinery/power/solar name = "solar panel" desc = "A solar electrical generator." @@ -22,7 +10,6 @@ var/list/solars_list = list() icon_state = "sp_base" anchored = 1 density = 1 - directwired = 1 use_power = 0 idle_power_usage = 0 active_power_usage = 0 @@ -30,26 +17,33 @@ var/list/solars_list = list() var/health = 10 var/obscured = 0 var/sunfrac = 0 - var/adir = SOUTH - var/ndir = SOUTH + var/adir = SOUTH // actual dir + var/ndir = SOUTH // target dir var/turn_angle = 0 var/obj/machinery/power/solar_control/control = null -/obj/machinery/power/solar/New(var/turf/loc, var/obj/item/solar_assembly/S, var/process = 1) +/obj/machinery/power/solar/New(var/turf/loc, var/obj/item/solar_assembly/S) ..(loc) Make(S) - connect_to_network(process) + connect_to_network() - -/obj/machinery/power/solar/disconnect_from_network() +/obj/machinery/power/solar/Destroy() + unset_control() //remove from control computer ..() - solars_list.Remove(src) -/obj/machinery/power/solar/connect_to_network(var/process) - ..() - if(process) - solars_list.Add(src) +//set the control of the panel to a given computer if closer than SOLAR_MAX_DIST +/obj/machinery/power/solar/proc/set_control(var/obj/machinery/power/solar_control/SC) + if(!SC || (get_dist(src, SC) > SOLAR_MAX_DIST)) + return 0 + control = SC + SC.connected_panels |= src + return 1 +//set the control of the panel to null and removes it from the control list of the previous control computer if needed +/obj/machinery/power/solar/proc/unset_control() + if(control) + control.connected_panels.Remove(src) + control = null /obj/machinery/power/solar/proc/Make(var/obj/item/solar_assembly/S) if(!S) @@ -57,22 +51,25 @@ var/list/solars_list = list() S.glass_type = /obj/item/stack/sheet/glass S.anchored = 1 S.loc = src + if(S.glass_type == /obj/item/stack/sheet/rglass) //if the panel is in reinforced glass + health *= 2 //this need to be placed here, because panels already on the map don't have an assembly linked to update_icon() -/obj/machinery/power/solar/attackby(obj/item/weapon/W, mob/user) +/obj/machinery/power/solar/attackby(obj/item/weapon/W, mob/user, params) - if(iscrowbar(W)) - playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1) + if(istype(W, /obj/item/weapon/crowbar)) + playsound(src.loc, 'sound/machines/click.ogg', 50, 1) + user.visible_message("[user] begins to take the glass off the solar panel.") if(do_after(user, 50)) var/obj/item/solar_assembly/S = locate() in src if(S) S.loc = src.loc S.give_glass() - playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) + playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) user.visible_message("[user] takes the glass off the solar panel.") - del(src) + qdel(src) return else if (W) src.add_fingerprint(user) @@ -92,9 +89,9 @@ var/list/solars_list = list() if(!(stat & BROKEN)) broken() else - getFromPool(/obj/item/weapon/shard, loc) - getFromPool(/obj/item/weapon/shard, loc) - del(src) + new /obj/item/weapon/shard(src.loc) + new /obj/item/weapon/shard(src.loc) + qdel(src) return return @@ -109,70 +106,58 @@ var/list/solars_list = list() src.dir = angle2dir(adir) return - +//calculates the fraction of the sunlight that the panel recieves /obj/machinery/power/solar/proc/update_solar_exposure() if(!sun) return if(obscured) sunfrac = 0 return - var/p_angle = abs((360+adir)%360 - (360+sun.angle)%360) + + //find the smaller angle between the direction the panel is facing and the direction of the sun (the sign is not important here) + var/p_angle = min(abs(adir - sun.angle), 360 - abs(adir - sun.angle)) + if(p_angle > 90) // if facing more than 90deg from sun, zero output sunfrac = 0 return - sunfrac = cos(p_angle) ** 2 + sunfrac = cos(p_angle) ** 2 + //isn't the power recieved from the incoming light proportionnal to cos(p_angle) (Lambert's cosine law) rather than cos(p_angle)^2 ? /obj/machinery/power/solar/process()//TODO: remove/add this from machines to save on processing as needed ~Carn PRIORITY - if(stat & BROKEN) return - if(!control) return + if(stat & BROKEN) + return + if(!sun || !control) //if there's no sun or the panel is not linked to a solar control computer, no need to proceed + return - if(adir != ndir) - adir = (360+adir+dd_range(-10,10,ndir-adir))%360 - update_icon() - update_solar_exposure() - - if(obscured) return - - var/sgen = SOLARGENRATE * sunfrac - add_avail(sgen) - if(powernet && control) - if(powernet.nodes[control]) + if(powernet) + if(powernet == control.powernet)//check if the panel is still connected to the computer + if(obscured) //get no light from the sun, so don't generate power + return + var/sgen = SOLARGENRATE * sunfrac + add_avail(sgen) control.gen += sgen - + else //if we're no longer on the same powernet, remove from control computer + unset_control() /obj/machinery/power/solar/proc/broken() + . = (!(stat & BROKEN)) stat |= BROKEN + unset_control() update_icon() return -/obj/machinery/power/solar/meteorhit() - if(stat & !BROKEN) - broken() - else - del(src) - - -/obj/machinery/power/solar/ex_act(severity) - switch(severity) - if(1.0) - qdel(src) - if(prob(15)) - getFromPool(/obj/item/weapon/shard, loc) - return - if(2.0) - if (prob(25)) - getFromPool(/obj/item/weapon/shard, loc) - qdel(src) - return - if (prob(50)) - broken() - if(3.0) - if (prob(25)) - broken() - return - +/obj/machinery/power/solar/ex_act(severity, target) + ..() + if(!gc_destroyed) + switch(severity) + if(2) + if(prob(50) && broken()) + new /obj/item/weapon/shard(src.loc) + if(3) + if(prob(25) && broken()) + new /obj/item/weapon/shard(src.loc) /obj/machinery/power/solar/blob_act() if(prob(75)) @@ -187,6 +172,29 @@ var/list/solars_list = list() . = PROCESS_KILL return +//trace towards sun to see if we're in shadow +/obj/machinery/power/solar/proc/occlusion() + + var/ax = x // start at the solar panel + var/ay = y + var/turf/T = null + + for(var/i = 1 to 20) // 20 steps is enough + ax += sun.dx // do step + ay += sun.dy + + T = locate( round(ax,0.5),round(ay,0.5),z) + + if(T.x == 1 || T.x==world.maxx || T.y==1 || T.y==world.maxy) // not obscured if we reach the edge + break + + if(T.density) // if we hit a solid turf, panel is obscured + obscured = 1 + return + + obscured = 0 // if hit the edge or stepped 20 times, not obscured + update_solar_exposure() + // // Solar Assembly - For construction of solar arrays. @@ -215,43 +223,45 @@ var/list/solars_list = list() glass_type = null -/obj/item/solar_assembly/attackby(var/obj/item/weapon/W, var/mob/user) +/obj/item/solar_assembly/attackby(var/obj/item/weapon/W, var/mob/user, params) if(!anchored && isturf(loc)) - if(iswrench(W)) + if(istype(W, /obj/item/weapon/wrench)) anchored = 1 user.visible_message("[user] wrenches the solar assembly into place.") - playsound(get_turf(src), 'sound/items/Ratchet.ogg', 75, 1) + playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) return 1 else - if(iswrench(W)) + if(istype(W, /obj/item/weapon/wrench)) anchored = 0 user.visible_message("[user] unwrenches the solar assembly from it's place.") - playsound(get_turf(src), 'sound/items/Ratchet.ogg', 75, 1) + playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) return 1 if(istype(W, /obj/item/stack/sheet/glass) || istype(W, /obj/item/stack/sheet/rglass)) var/obj/item/stack/sheet/S = W - if(S.amount >= 2) + if(S.use(2)) glass_type = W.type - S.use(2) - playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1) + playsound(src.loc, 'sound/machines/click.ogg', 50, 1) user.visible_message("[user] places the glass on the solar assembly.") if(tracker) new /obj/machinery/power/tracker(get_turf(src), src) else new /obj/machinery/power/solar(get_turf(src), src) + else + user << "You need two sheets of glass to put them into a solar panel." + return return 1 if(!tracker) if(istype(W, /obj/item/weapon/tracker_electronics)) tracker = 1 user.drop_item() - del(W) + qdel(W) user.visible_message("[user] inserts the electronics into the solar assembly.") return 1 else - if(iscrowbar(W)) + if(istype(W, /obj/item/weapon/crowbar)) new /obj/item/weapon/tracker_electronics(src.loc) tracker = 0 user.visible_message("[user] takes out the electronics from the solar assembly.") @@ -269,18 +279,18 @@ var/list/solars_list = list() icon_state = "solar" anchored = 1 density = 1 - directwired = 1 use_power = 1 - idle_power_usage = 5 - active_power_usage = 20 + idle_power_usage = 250 var/id = 0 var/cdir = 0 + var/targetdir = 0 // target angle in manual tracking (since it updates every game minute) var/gen = 0 var/lastgen = 0 - var/track = 0 // 0=off 1=manual 2=automatic - var/trackrate = 60 // Measured in tenths of degree per minute (i.e. defaults to 6.0 deg/min) - var/trackdir = 1 // -1=CCW, 1=CW - var/nexttime = 0 // Next clock time that manual tracking will move the array + var/track = 0 // 0= off 1=timed 2=auto (tracker) + var/trackrate = 600 // 300-900 seconds + var/nexttime = 0 // time for a panel to rotate of 1� in manual tracking + var/obj/machinery/power/tracker/connected_tracker = null + var/list/connected_panels = list() /obj/machinery/power/solar_control/New() @@ -289,14 +299,53 @@ var/list/solars_list = list() initialize() connect_to_network() +/obj/machinery/power/solar_control/Destroy() + for(var/obj/machinery/power/solar/M in connected_panels) + M.unset_control() + if(connected_tracker) + connected_tracker.unset_control() + ..() + /obj/machinery/power/solar_control/disconnect_from_network() ..() solars_list.Remove(src) /obj/machinery/power/solar_control/connect_to_network() - ..() + var/to_return = ..() + if(powernet) //if connected and not already in solar_list... + solars_list |= src //... add it + return to_return + +//search for unconnected panels and trackers in the computer powernet and connect them +/obj/machinery/power/solar_control/proc/search_for_connected() if(powernet) - solars_list.Add(src) + for(var/obj/machinery/power/M in powernet.nodes) + if(istype(M, /obj/machinery/power/solar)) + var/obj/machinery/power/solar/S = M + if(!S.control) //i.e unconnected + S.set_control(src) + else if(istype(M, /obj/machinery/power/tracker)) + if(!connected_tracker) //if there's already a tracker connected to the computer don't add another + var/obj/machinery/power/tracker/T = M + if(!T.control) //i.e unconnected + T.set_control(src) + +//called by the sun controller, update the facing angle (either manually or via tracking) and rotates the panels accordingly +/obj/machinery/power/solar_control/proc/update() + if(stat & (NOPOWER | BROKEN)) + return + + switch(track) + if(1) + if(trackrate) //we're manual tracking. If we set a rotation speed... + cdir = targetdir //...the current direction is the targetted one (and rotates panels to it) + if(2) // auto-tracking + if(connected_tracker) + connected_tracker.set_angle(sun.angle) + + set_panels(cdir) + updateDialog() + /obj/machinery/power/solar_control/initialize() ..() @@ -314,32 +363,47 @@ var/list/solars_list = list() return icon_state = "solar" overlays.Cut() - if(cdir > 0) + if(cdir > -1) overlays += image('icons/obj/computer.dmi', "solcon-o", FLY_LAYER, angle2dir(cdir)) return - -/obj/machinery/power/solar_control/attack_ai(mob/user) - src.add_hiddenprint(user) - add_fingerprint(user) - if(stat & (BROKEN | NOPOWER)) return - interact(user) - - /obj/machinery/power/solar_control/attack_hand(mob/user) - add_fingerprint(user) - if(stat & (BROKEN | NOPOWER)) return - interact(user) + if(!..()) + ui_interact(user) +/obj/machinery/power/solar_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) -/obj/machinery/power/solar_control/attackby(I as obj, user as mob) + var/data = list() + + data["generated"] = round(lastgen) + data["angle"] = cdir + data["direction"] = angle2text(cdir) + + data["tracking_state"] = track + data["tracking_rate"] = trackrate + data["rotating_way"] = (trackrate<0 ? "CCW" : "CW") + + data["connected_panels"] = connected_panels.len + data["connected_tracker"] = (connected_tracker ? 1 : 0) + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "solar_control.tmpl", name, 490, 420) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + else + ui.push_data(data) + return + +/obj/machinery/power/solar_control/attackby(I as obj, user as mob, params) if(istype(I, /obj/item/weapon/screwdriver)) - playsound(get_turf(src), 'sound/items/Screwdriver.ogg', 50, 1) + 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." + user << "The broken glass falls out." var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) - getFromPool(/obj/item/weapon/shard, loc) + new /obj/item/weapon/shard( src.loc ) var/obj/item/weapon/circuitboard/solar_control/M = new /obj/item/weapon/circuitboard/solar_control( A ) for (var/obj/C in src) C.loc = src.loc @@ -347,9 +411,9 @@ var/list/solars_list = list() A.state = 3 A.icon_state = "3" A.anchored = 1 - del(src) + qdel(src) else - user << "\blue You disconnect the monitor." + user << "You disconnect the monitor." var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) var/obj/item/weapon/circuitboard/solar_control/M = new /obj/item/weapon/circuitboard/solar_control( A ) for (var/obj/C in src) @@ -358,12 +422,11 @@ var/list/solars_list = list() A.state = 4 A.icon_state = "4" A.anchored = 1 - del(src) + qdel(src) else src.attack_hand(user) return - /obj/machinery/power/solar_control/process() lastgen = gen gen = 0 @@ -371,139 +434,64 @@ var/list/solars_list = list() if(stat & (NOPOWER | BROKEN)) return - use_power(250) - if(track==1 && nexttime < world.time && trackdir*trackrate) - // Increments nexttime using itself and not world.time to prevent drift - nexttime = nexttime + 6000/trackrate - // Nudges array 1 degree in desired direction - cdir = (cdir+trackdir+360)%360 - set_panels(cdir) - update_icon() - - src.updateDialog() - - -// called by solar tracker when sun position changes -/obj/machinery/power/solar_control/proc/tracker_update(var/angle) - if(track != 2 || stat & (NOPOWER | BROKEN)) - return - cdir = angle - set_panels(cdir) - update_icon() - src.updateDialog() - - -/obj/machinery/power/solar_control/interact(mob/user) - if(stat & (BROKEN | NOPOWER)) return - if ( (get_dist(src, user) > 1 )) - if (!istype(user, /mob/living/silicon/ai)) - user.unset_machine() - user << browse(null, "window=solcon") - return - - add_fingerprint(user) - user.set_machine(src) - - - // AUTOFIXED BY fix_string_idiocy.py - // C:\Users\Rob\Documents\Projects\vgstation13\code\modules\power\solar.dm:407: var/t = "Solar Generator Control
"
-	var/t = {"Solar Generator Control
-Generated power : [round(lastgen)] W
-Station Rotational Period: [60/abs(sun.rate)] minutes
-Station Rotational Direction: [sun.rate<0 ? "CCW" : "CW"]
-Star Orientation: [sun.angle]° ([angle2text(sun.angle)])
-Array Orientation: [rate_control(src,"cdir","[cdir]°",1,10,60)] ([angle2text(cdir)])
-


-Tracking:"} - // END AUTOFIX - switch(track) - if(0) - t += "Off Manual Automatic
" - if(1) - t += "Off Manual Automatic
" - if(2) - t += "Off Manual Automatic
" - - - // AUTOFIXED BY fix_string_idiocy.py - // C:\Users\Rob\Documents\Projects\vgstation13\code\modules\power\solar.dm:423: t += "Manual Tracking Rate: [rate_control(src,"tdir","[trackrate/10]°/min ([trackdir<0 ? "CCW" : "CW"])",1,10)]
" - t += {"Manual Tracking Rate: [rate_control(src,"tdir","[trackrate/10]°/min ([trackdir<0 ? "CCW" : "CW"])",1,10)]
-Manual Tracking Direction:"} - // END AUTOFIX - switch(trackdir) - if(-1) - t += "CW CCW
" - if(1) - t += "CW CCW
" - t += "Close
" - user << browse(t, "window=solcon") - onclose(user, "solcon") - return + if(connected_tracker) //NOTE : handled here so that we don't add trackers to the processing list + if(connected_tracker.powernet != powernet) + connected_tracker.unset_control() + if(track==1 && trackrate) //manual tracking and set a rotation speed + if(nexttime <= world.time) //every time we need to increase/decrease the angle by 1�... + targetdir = (targetdir + trackrate/abs(trackrate) + 360) % 360 //... do it + nexttime += 36000/abs(trackrate) //reset the counter for the next 1� /obj/machinery/power/solar_control/Topic(href, href_list) if(..()) - usr << browse(null, "window=solcon") - usr.unset_machine() return - if(href_list["close"] ) - usr << browse(null, "window=solcon") - usr.unset_machine() - return - - if(href_list["dir"]) - cdir = text2num(href_list["dir"]) - set_panels(cdir) - update_icon() - - if(href_list["rate control"]) + + if(href_list["rate_control"]) if(href_list["cdir"]) src.cdir = dd_range(0,359,(360+src.cdir+text2num(href_list["cdir"]))%360) + src.targetdir = src.cdir + if(track == 2) //manual update, so losing auto-tracking + track = 0 spawn(1) set_panels(cdir) - update_icon() if(href_list["tdir"]) - src.trackrate = dd_range(0,360,src.trackrate+text2num(href_list["tdir"])) - if(src.trackrate) nexttime = world.time + 6000/trackrate + src.trackrate = dd_range(-7200,7200,src.trackrate+text2num(href_list["tdir"])) + if(src.trackrate) nexttime = world.time + 36000/abs(trackrate) if(href_list["track"]) - if(src.trackrate) nexttime = world.time + 6000/trackrate track = text2num(href_list["track"]) - if(powernet && (track == 2)) - if(!solars_list.Find(src,1,0) || !(locate(src) in solars_list) || !(src in solars_list)) - solars_list.Add(src) - for(var/obj/machinery/power/tracker/T in get_solars_powernet()) - if(powernet.nodes[T]) - cdir = T.sun_angle - break + if(track == 2) + if(connected_tracker) + connected_tracker.set_angle(sun.angle) + set_panels(cdir) + else if (track == 1) //begin manual tracking + src.targetdir = src.cdir + if(src.trackrate) nexttime = world.time + 36000/abs(trackrate) + set_panels(targetdir) - if(href_list["trackdir"]) - trackdir = text2num(href_list["trackdir"]) + if(href_list["search_connected"]) + search_for_connected() + if(connected_tracker && track == 2) + connected_tracker.set_angle(sun.angle) + set_panels(cdir) - set_panels(cdir) - update_icon() - src.updateUsrDialog() return - +//rotates the panel to the passed angle /obj/machinery/power/solar_control/proc/set_panels(var/cdir) - if(!powernet) return - for(var/obj/machinery/power/solar/S in get_solars_powernet()) - if(powernet.nodes[S]) - if(get_dist(S, src) < SOLAR_MAX_DIST) - if(!S.control) - S.control = src - S.ndir = cdir + + for(var/obj/machinery/power/solar/S in connected_panels) + S.adir = cdir //instantly rotates the panel + S.occlusion()//and + S.update_icon() //update it + + update_icon() /obj/machinery/power/solar_control/power_change() - if(powered()) - stat &= ~NOPOWER - update_icon() - else - spawn(rand(0, 15)) - stat |= NOPOWER - update_icon() + ..() + update_icon() /obj/machinery/power/solar_control/proc/broken() @@ -511,25 +499,16 @@ Manual Tracking Direction:"} update_icon() -/obj/machinery/power/solar_control/meteorhit() - broken() - return - - -/obj/machinery/power/solar_control/ex_act(severity) - switch(severity) - if(1.0) - //SN src = null - qdel(src) - return - if(2.0) - if (prob(50)) - broken() - if(3.0) - if (prob(25)) - broken() - return - +/obj/machinery/power/solar_control/ex_act(severity, target) + ..() + if(!gc_destroyed) + switch(severity) + if(2) + if(prob(50)) + broken() + if(3) + if(prob(25)) + broken() /obj/machinery/power/solar_control/blob_act() if (prob(75)) @@ -543,4 +522,4 @@ Manual Tracking Direction:"} /obj/item/weapon/paper/solar name = "paper- 'Going green! Setup your own solar array instructions.'" - info = "

Welcome

At greencorps we love the environment, and space. With this package you are able to help mother nature and produce energy without any usage of fossil fuel or plasma! Singularity energy is dangerous while solar energy is safe, which is why it's better. Now here is how you setup your own solar array.

You can make a solar panel by wrenching the solar assembly onto a cable node. Adding a glass panel, reinforced or regular glass will do, will finish the construction of your solar panel. It is that easy!.

Now after setting up 19 more of these solar panels you will want to create a solar tracker to keep track of our mother nature's gift, the sun. These are the same steps as before except you insert the tracker equipment circuit into the assembly before performing the final step of adding the glass. You now have a tracker! Now the last step is to add a computer to calculate the sun's movements and to send commands to the solar panels to change direction with the sun. Setting up the solar computer is the same as setting up any computer, so you should have no trouble in doing that. You do need to put a wire node under the computer, and the wire needs to be connected to the tracker.

Congratulations, you should have a working solar array. If you are having trouble, here are some tips. Make sure all solar equipment are on a cable node, even the computer. You can always deconstruct your creations if you make a mistake.

That's all to it, be safe, be green!

" + info = "

Welcome

At greencorps we love the environment, and space. With this package you are able to help mother nature and produce energy without any usage of fossil fuel or plasma! Singularity energy is dangerous while solar energy is safe, which is why it's better. Now here is how you setup your own solar array.

You can make a solar panel by wrenching the solar assembly onto a cable node. Adding a glass panel, reinforced or regular glass will do, will finish the construction of your solar panel. It is that easy!

Now after setting up 19 more of these solar panels you will want to create a solar tracker to keep track of our mother nature's gift, the sun. These are the same steps as before except you insert the tracker equipment circuit into the assembly before performing the final step of adding the glass. You now have a tracker! Now the last step is to add a computer to calculate the sun's movements and to send commands to the solar panels to change direction with the sun. Setting up the solar computer is the same as setting up any computer, so you should have no trouble in doing that. You do need to put a wire node under the computer, and the wire needs to be connected to the tracker.

Congratulations, you should have a working solar array. If you are having trouble, here are some tips. Make sure all solar equipment are on a cable node, even the computer. You can always deconstruct your creations if you make a mistake.

That's all to it, be safe, be green!

" \ No newline at end of file diff --git a/code/modules/power/switch.dm b/code/modules/power/switch.dm index 05683bd9c57..8c846cdb76b 100644 --- a/code/modules/power/switch.dm +++ b/code/modules/power/switch.dm @@ -10,7 +10,6 @@ icon_state = "switch-dbl-up" var/icon_state_on = "switch-dbl-down" var/icon_state_off = "switch-dbl-up" - flags = FPRINT density = 0 anchored = 1 var/on = 0 //up is off, down is on diff --git a/code/modules/power/tracker.dm b/code/modules/power/tracker.dm index d35cf81ed45..9b66f6afb91 100644 --- a/code/modules/power/tracker.dm +++ b/code/modules/power/tracker.dm @@ -10,78 +10,70 @@ icon_state = "tracker" anchored = 1 density = 1 - directwired = 1 use_power = 0 + var/id = 0 var/sun_angle = 0 // sun angle as set by sun datum + var/obj/machinery/power/solar_control/control = null /obj/machinery/power/tracker/New(var/turf/loc, var/obj/item/solar_assembly/S) ..(loc) + Make(S) + connect_to_network() + +/obj/machinery/power/tracker/Destroy() + unset_control() //remove from control computer + ..() + +//set the control of the tracker to a given computer if closer than SOLAR_MAX_DIST +/obj/machinery/power/tracker/proc/set_control(var/obj/machinery/power/solar_control/SC) + if(!SC || (get_dist(src, SC) > SOLAR_MAX_DIST)) + return 0 + control = SC + SC.connected_tracker = src + return 1 + +//set the control of the tracker to null and removes it from the previous control computer if needed +/obj/machinery/power/tracker/proc/unset_control() + if(control) + control.connected_tracker = null + control = null + +/obj/machinery/power/tracker/proc/Make(var/obj/item/solar_assembly/S) if(!S) S = new /obj/item/solar_assembly(src) S.glass_type = /obj/item/stack/sheet/glass S.tracker = 1 S.anchored = 1 S.loc = src - connect_to_network() + update_icon() -/obj/machinery/power/tracker/disconnect_from_network() - ..() - solars_list.Remove(src) - -/obj/machinery/power/tracker/connect_to_network() - ..() - solars_list.Add(src) - -// called by datum/sun/calc_position() as sun's angle changes +//updates the tracker icon and the facing angle for the control computer /obj/machinery/power/tracker/proc/set_angle(var/angle) sun_angle = angle //set icon dir to show sun illumination dir = turn(NORTH, -angle - 22.5) // 22.5 deg bias ensures, e.g. 67.5-112.5 is EAST - // check we can draw power - if(stat & NOPOWER) - return + if(powernet && (powernet == control.powernet)) //update if we're still in the same powernet + control.cdir = angle - // find all solar controls and update them - // currently, just update all controllers in world - // ***TODO: better communication system using network - if(powernet) - for(var/obj/machinery/power/solar_control/C in get_solars_powernet()) - if(powernet.nodes[C]) - if(get_dist(C, src) < SOLAR_MAX_DIST) - C.tracker_update(angle) +/obj/machinery/power/tracker/attackby(var/obj/item/weapon/W, var/mob/user, params) - -/obj/machinery/power/tracker/attackby(var/obj/item/weapon/W, var/mob/user) - - if(iscrowbar(W)) - playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1) + if(istype(W, /obj/item/weapon/crowbar)) + playsound(src.loc, 'sound/machines/click.ogg', 50, 1) + user.visible_message("[user] begins to take the glass off the solar tracker.") if(do_after(user, 50)) var/obj/item/solar_assembly/S = locate() in src if(S) S.loc = src.loc S.give_glass() - playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) + playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) user.visible_message("[user] takes the glass off the tracker.") - del(src) + qdel(src) return ..() -// timed process -// make sure we can draw power from the powernet -/obj/machinery/power/tracker/process() - - var/avail = surplus() - - if(avail > 500) - add_load(500) - stat &= ~NOPOWER - else - stat |= NOPOWER - - // Tracker Electronic /obj/item/weapon/tracker_electronics diff --git a/code/modules/power/turbine.dm b/code/modules/power/turbine.dm index 4baa6efe685..cf35f456da8 100644 --- a/code/modules/power/turbine.dm +++ b/code/modules/power/turbine.dm @@ -222,7 +222,7 @@ doors += P /* -/obj/machinery/computer/turbine_computer/attackby(I as obj, user as mob) +/obj/machinery/computer/turbine_computer/attackby(I as obj, user as mob, params) if(istype(I, /obj/item/weapon/screwdriver)) playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) if(do_after(user, 20)) diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index b84eb480138..136d589b75d 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -3,7 +3,7 @@ desc = "A bullet casing." icon = 'icons/obj/ammo.dmi' icon_state = "s-casing" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT throwforce = 1 w_class = 1.0 @@ -30,7 +30,7 @@ -/obj/item/ammo_casing/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/ammo_casing/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/screwdriver)) if(BB) if(initial(BB.name) == "bullet") @@ -57,7 +57,7 @@ desc = "A box of ammo?" icon_state = "357" icon = 'icons/obj/ammo.dmi' - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT item_state = "syringe_kit" m_amt = 30000 @@ -95,7 +95,7 @@ return 1 return 0 -/obj/item/ammo_box/attackby(var/obj/item/A as obj, mob/user as mob, var/silent = 0) +/obj/item/ammo_box/attackby(var/obj/item/A as obj, mob/user as mob, var/silent = 0, params) var/num_loaded = 0 if(istype(A, /obj/item/ammo_box)) var/obj/item/ammo_box/AM = A diff --git a/code/modules/projectiles/ammunition/ammo_casings.dm b/code/modules/projectiles/ammunition/ammo_casings.dm index 27a669cf98f..e94ad8a54b0 100644 --- a/code/modules/projectiles/ammunition/ammo_casings.dm +++ b/code/modules/projectiles/ammunition/ammo_casings.dm @@ -96,6 +96,12 @@ icon_state = "ishell" projectile_type = "/obj/item/projectile/bullet/incendiary/shell" +/obj/item/ammo_casing/shotgun/frag12 + name = "FRAG-12 slug" + desc = "A high explosive breaching round for a 12 gauge shotgun." + icon_state = "heshell" + projectile_type = /obj/item/projectile/bullet/frag12 + /obj/item/ammo_casing/shotgun/incendiary/dragonsbreath name = "dragonsbreath shell" desc = "A shotgun shell which fires a spread of incendiary pellets." @@ -125,6 +131,11 @@ /obj/item/ammo_casing/shotgun/dart/attackby() return +/obj/item/ammo_casing/syringegun + name = "syringe gun spring" + desc = "A high-power spring that throws syringes." + projectile_type = null + /obj/item/ammo_casing/shotgun/fakebeanbag name = "beanbag shell" desc = "A weak beanbag shell." @@ -133,6 +144,7 @@ /obj/item/ammo_casing/a762 desc = "A 7.62mm bullet casing." + icon_state = "762-casing" caliber = "a762" projectile_type = "/obj/item/projectile/bullet" diff --git a/code/modules/projectiles/ammunition/boxes.dm b/code/modules/projectiles/ammunition/boxes.dm index 72aa816d1cc..bd0e398723f 100644 --- a/code/modules/projectiles/ammunition/boxes.dm +++ b/code/modules/projectiles/ammunition/boxes.dm @@ -40,6 +40,14 @@ max_ammo = 4 multiple_sprites = 1 +/obj/item/ammo_box/a762 + name = "stripper clip (7.62mm)" + desc = "A stripper clip." + icon_state = "762" + ammo_type = /obj/item/ammo_casing/a762 + max_ammo = 5 + multiple_sprites = 1 + /obj/item/ammo_box/shotgun name = "Ammunition Box (slug)" icon_state = "9mmbox" diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index 9e333f5c82a..be084ebca0e 100644 --- a/code/modules/projectiles/ammunition/magazines.dm +++ b/code/modules/projectiles/ammunition/magazines.dm @@ -86,6 +86,14 @@ ammo_type = "/obj/item/ammo_casing/a40mm" max_ammo = 6 +/obj/item/ammo_box/magazine/internal/boltaction + name = "bolt action rifle internal magazine" + desc = "Oh god, this shouldn't be here" + ammo_type = "/obj/item/ammo_casing/a762" + caliber = "a762" + max_ammo = 5 + multiload = 1 + ///////////EXTERNAL MAGAZINES//////////////// /obj/item/ammo_box/magazine/m10mm @@ -180,10 +188,10 @@ icon_state = "[initial(icon_state)]-[round(ammo_count(),10)]" /obj/item/ammo_box/magazine/m12g - name = "shotgun magazine (12g taser slugs)" - icon_state = "m12gs" + name = "shotgun magazine (12g buckshot)" + icon_state = "m12gb" + ammo_type = "/obj/item/ammo_casing/shotgun/buckshot" origin_tech = "combat=3;syndicate=1" - ammo_type = "/obj/item/ammo_casing/shotgun/stunslug" caliber = "shotgun" max_ammo = 8 @@ -192,10 +200,10 @@ icon_state = "[initial(icon_state)]-[Ceiling(ammo_count(0)/8)*8]" -/obj/item/ammo_box/magazine/m12g/buckshot - name = "shotgun magazine (12g buckshot)" - icon_state = "m12gb" - ammo_type = "/obj/item/ammo_casing/shotgun/buckshot" +/obj/item/ammo_box/magazine/m12g/stun + name = "shotgun magazine (12g taser slugs)" + icon_state = "m12gs" + ammo_type = "/obj/item/ammo_casing/shotgun/stunslug" /obj/item/ammo_box/magazine/m12g/dragon diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index c32f3973882..6500acbaf88 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/gun.dmi' icon_state = "detective" item_state = "gun" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT m_amt = 2000 w_class = 3.0 @@ -36,6 +36,7 @@ var/last_fired = 0 var/obj/item/device/flashlight/F = null var/can_flashlight = 0 + var/heavy_weapon = 0 proc/ready_to_fire() if(world.time >= last_fired + fire_delay) @@ -78,15 +79,15 @@ return 1 /obj/item/weapon/gun/proc/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0)//TODO: go over this - //Exclude lasertag guns from the M_CLUMSY check. + //Exclude lasertag guns from the CLUMSY check. if(clumsy_check) if(istype(user, /mob/living)) var/mob/living/M = user - if ((M_CLUMSY in M.mutations) && prob(50)) + if ((CLUMSY in M.mutations) && prob(50)) M << "[src] blows up in your face." M.take_organ_damage(0,20) M.drop_item() - del(src) + qdel(src) return if (!user.IsAdvancedToolUser() || istype(user, /mob/living/carbon/monkey/diona)) @@ -94,7 +95,7 @@ return if(istype(user, /mob/living)) var/mob/living/M = user - if (M_HULK in M.mutations) + if (HULK in M.mutations) M << "\red Your meaty finger is much too large for the trigger guard!" return if(ishuman(user)) @@ -122,12 +123,18 @@ if(!in_chamber) return + + if(heavy_weapon) + if(user.get_inactive_hand()) + recoil = 4 //one-handed kick + else + recoil = initial(recoil) in_chamber.firer = user in_chamber.def_zone = user.zone_sel.selecting if(targloc == curloc) user.bullet_act(in_chamber) - del(in_chamber) + qdel(in_chamber) update_icon() return @@ -142,6 +149,12 @@ user.visible_message("[user] fires [src][reflex ? " by reflex":""]!", \ "You fire [src][reflex ? "by reflex":""]!", \ "You hear a [istype(in_chamber, /obj/item/projectile/beam) ? "laser blast" : "gunshot"]!") + + if(heavy_weapon) + if(user.get_inactive_hand()) + if(prob(15)) + user.visible_message("[src] flies out of [user]'s hands!", "[src] kicks out of your grip!") + user.drop_item() if (istype(in_chamber, /obj/item/projectile/bullet/blank)) // A hacky way of making blank shotgun shells work again. Honk. in_chamber.delete() @@ -153,7 +166,7 @@ in_chamber.loc = get_turf(user) in_chamber.starting = get_turf(user) in_chamber.shot_from = src - user.next_move = world.time + 4 + user.changeNext_move(CLICK_CD_RANGE) in_chamber.silenced = silenced in_chamber.current = curloc in_chamber.yo = targloc.y - curloc.y @@ -276,7 +289,7 @@ return ..() //Pistolwhippin' -/obj/item/weapon/gun/attackby(var/obj/item/A as obj, mob/user as mob) +/obj/item/weapon/gun/attackby(var/obj/item/A as obj, mob/user as mob, params) if(istype(A, /obj/item/device/flashlight/seclite)) var/obj/item/device/flashlight/seclite/S = A if(can_flashlight) @@ -292,6 +305,7 @@ A.loc = src update_icon() update_gunlight(user) + verbs += /obj/item/weapon/gun/proc/toggle_gunlight if(istype(A, /obj/item/weapon/screwdriver)) if(F) if(user.l_hand != src && user.r_hand != src) @@ -304,13 +318,18 @@ update_gunlight(user) S.update_brightness(user) update_icon() + verbs -= /obj/item/weapon/gun/proc/toggle_gunlight ..() return -/obj/item/weapon/gun/verb/toggle_gunlight() +/obj/item/weapon/gun/proc/toggle_gunlight() set name = "Toggle Gunlight" set category = "Object" set desc = "Click to toggle your weapon's attached flashlight." + + if(!F) + return + var/mob/living/carbon/human/user = usr if(!isturf(user.loc)) user << "You cannot turn the light on while in this [user.loc]." diff --git a/code/modules/projectiles/guns/alien.dm b/code/modules/projectiles/guns/alien.dm index 76ea406751b..177255cfe72 100644 --- a/code/modules/projectiles/guns/alien.dm +++ b/code/modules/projectiles/guns/alien.dm @@ -77,7 +77,7 @@ force = 10 projectile_type = "/obj/item/projectile/energy/sonic" - cell_type = "/obj/item/weapon/cell/super" + cell_type = "/obj/item/weapon/stock_parts/cell/super" fire_delay = 40 fire_sound = 'sound/effects/basscannon.ogg' diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 3d09aadc2c6..befa0720b66 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -4,16 +4,15 @@ desc = "A basic energy-based gun." fire_sound = 'sound/weapons/Taser.ogg' - var/obj/item/weapon/cell/power_supply //What type of power cell this uses + var/obj/item/weapon/stock_parts/cell/power_supply //What type of power cell this uses var/charge_cost = 1000 //How much energy is needed to fire. - var/cell_type = "/obj/item/weapon/cell" + var/cell_type = "/obj/item/weapon/stock_parts/cell" var/projectile_type = "/obj/item/projectile/beam" var/modifystate emp_act(severity) - power_supply.use(round(power_supply.maxcharge / severity)) + power_supply.use(round(power_supply.charge / severity)) update_icon() - ..() New() @@ -54,8 +53,8 @@ return /* - attackby(obj/item/weapon/W, mob/user) - if(istype(W, /obj/item/weapon/cell)) + attackby(obj/item/weapon/W, mob/user, params) + if(istype(W, /obj/item/weapon/stock_parts/cell)) if(!power_supply) user.drop_item() W.loc = src diff --git a/code/modules/projectiles/guns/energy/advtaser.dm b/code/modules/projectiles/guns/energy/advtaser.dm index ff552909ab8..b63c9dfbf16 100644 --- a/code/modules/projectiles/guns/energy/advtaser.dm +++ b/code/modules/projectiles/guns/energy/advtaser.dm @@ -4,13 +4,14 @@ icon_state = "advtaser" item_state = null //so the human update icon uses the icon_state instead. icon_override = 'icons/mob/in-hand/guns.dmi' - cell_type = "/obj/item/weapon/cell" + cell_type = "/obj/item/weapon/stock_parts/cell" origin_tech = null fire_sound = 'sound/weapons/Taser.ogg' projectile_type = "/obj/item/projectile/energy/electrode" charge_cost = 2000 modifystate = "advtaserstun" can_flashlight = 1 + fire_delay = 20 var/mode = 0 //0 = stun, 1 = disable @@ -24,6 +25,7 @@ user << "\red [src.name] is now set to Disable." projectile_type = "/obj/item/projectile/beam/disabler" modifystate = "advtaserdisable" + fire_delay = 0 if(1) mode = 0 charge_cost = 2000 @@ -31,6 +33,7 @@ user << "\red [src.name] is now set to stun." projectile_type = "/obj/item/projectile/energy/electrode" modifystate = "advtaserstun" + fire_delay = 20 update_icon() if(user.l_hand == src) user.update_inv_l_hand() diff --git a/code/modules/projectiles/guns/energy/hos.dm b/code/modules/projectiles/guns/energy/hos.dm new file mode 100644 index 00000000000..b1b932c38d9 --- /dev/null +++ b/code/modules/projectiles/guns/energy/hos.dm @@ -0,0 +1,45 @@ +/obj/item/weapon/gun/energy/hos + name = "HoS Energy Gun" + desc = "This is a modern recreation of the captain's antique laser gun. This gun has several unique firemodes, but lacks the ability to recharge over time." + icon_state = "hoslaser" + item_state = null //so the human update icon uses the icon_state instead. + icon_override = 'icons/mob/in-hand/guns.dmi' + force = 10 + fire_sound = 'sound/weapons/Taser.ogg' + origin_tech = "combat=3;magnets=2" + charge_cost = 2000 + modifystate = "hoslaserstun" + projectile_type = "/obj/item/projectile/energy/electrode" + var/mode = 2 + + attack_self(mob/living/user as mob) + switch(mode) + if(2) + mode = 0 + charge_cost = 1000 + fire_sound = 'sound/weapons/Laser.ogg' + user << "\red [src.name] is now set to kill." + projectile_type = "/obj/item/projectile/beam" + modifystate = "hoslaserkill" + fire_delay = 0 + if(0) + mode = 1 + charge_cost = 500 + fire_sound = 'sound/weapons/taser2.ogg' + user << "\red [src.name] is now set to disable." + projectile_type = "/obj/item/projectile/beam/disabler" + modifystate = "hoslaserdisable" + fire_delay = 0 + if(1) + mode = 2 + charge_cost = 2000 + fire_sound = 'sound/weapons/taser.ogg' + user << "\red [src.name] is now set to stun." + projectile_type = "/obj/item/projectile/energy/electrode" + modifystate = "hoslaserstun" + fire_delay = 20 + update_icon() + if(user.l_hand == src) + user.update_inv_l_hand() + else + user.update_inv_r_hand() \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 51a607890a0..3e6679a189e 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -24,6 +24,8 @@ obj/item/weapon/gun/energy/laser/retro /obj/item/weapon/gun/energy/laser/captain icon_state = "caplaser" + item_state = "caplaser" + icon_override = 'icons/mob/in-hand/guns.dmi' desc = "This is an antique laser gun. All craftsmanship is of the highest quality. It is decorated with assistant leather and chrome. The object menaces with spikes of energy. On the item is an image of Space Station 13. The station is exploding." force = 10 origin_tech = null @@ -78,7 +80,7 @@ obj/item/weapon/gun/energy/laser/retro item_state = "laser" w_class = 4.0 force = 10 - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BACK fire_sound = 'sound/weapons/lasercannonfire.ogg' origin_tech = "combat=4;materials=3;powerstorage=3" diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index 39395e3a064..8f5a2f470e4 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -43,9 +43,6 @@ desc = "An energy gun with an experimental miniaturized reactor." icon_state = "nucgun" origin_tech = "combat=3;materials=5;powerstorage=3" - charge_cost = 1000 - fire_sound = 'sound/weapons/Taser.ogg' - projectile_type = "/obj/item/projectile/energy/electrode" var/lightfail = 0 var/charge_tick = 0 can_flashlight = 0 @@ -120,9 +117,6 @@ update_mode() if (mode == 0) overlays += "nucgun-stun" - charge_cost = 1000 - fire_sound = 'sound/weapons/Taser.ogg' - projectile_type = "/obj/item/projectile/energy/electrode" else if (mode == 1) overlays += "nucgun-kill" @@ -136,3 +130,43 @@ update_charge() update_reactor() update_mode() + + +/obj/item/weapon/gun/energy/gun/turret + name = "hybrid turret gun" + desc = "A heavy hybrid energy cannon with two settings: Stun and kill." + icon_state = "turretlaser" + slot_flags = null + w_class = 5 + heavy_weapon = 1 + can_flashlight = 0 + projectile_type = /obj/item/projectile/energy/electrode + charge_cost = 1000 + fire_delay = 20 + +/obj/item/weapon/gun/energy/gun/turret/update_icon() + icon_state = initial(icon_state) + +/obj/item/weapon/gun/energy/gun/turret/attack_self(mob/living/user as mob) + switch(mode) + if(0) + mode = 1 + charge_cost = 500 + fire_sound = 'sound/weapons/Laser.ogg' + user << "\red [src.name] is now set to kill." + projectile_type = /obj/item/projectile/beam + modifystate = "energykill" + fire_delay = 0 + if(1) + mode = 0 + charge_cost = 1000 + fire_sound = 'sound/weapons/Taser.ogg' + user << "\red [src.name] is now set to stun." + projectile_type = /obj/item/projectile/energy/electrode + modifystate = "energystun" + fire_delay = 20 + update_icon() + if(user.l_hand == src) + user.update_inv_l_hand() + else + user.update_inv_r_hand() \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy/pulse.dm b/code/modules/projectiles/guns/energy/pulse.dm index e11a604b45e..3591d84008b 100644 --- a/code/modules/projectiles/guns/energy/pulse.dm +++ b/code/modules/projectiles/guns/energy/pulse.dm @@ -7,7 +7,7 @@ fire_sound = 'sound/weapons/pulse.ogg' charge_cost = 200 projectile_type = "/obj/item/projectile/beam/pulse" - cell_type = "/obj/item/weapon/cell/super" + cell_type = "/obj/item/weapon/stock_parts/cell/super" var/mode = 2 slot_flags = SLOT_BACK w_class = 4.0 @@ -16,22 +16,25 @@ switch(mode) if(2) mode = 0 - charge_cost = 100 + charge_cost = 50 fire_sound = 'sound/weapons/Taser.ogg' user << "\red [src.name] is now set to stun." projectile_type = "/obj/item/projectile/energy/electrode" + fire_delay = 20 if(0) mode = 1 charge_cost = 100 fire_sound = 'sound/weapons/Laser.ogg' user << "\red [src.name] is now set to kill." projectile_type = "/obj/item/projectile/beam" + fire_delay = 0 if(1) mode = 2 charge_cost = 200 fire_sound = 'sound/weapons/pulse.ogg' user << "\red [src.name] is now set to DESTROY." projectile_type = "/obj/item/projectile/beam/pulse" + fire_delay = 0 return isHandgun() @@ -52,19 +55,36 @@ /obj/item/weapon/gun/energy/pulse_rifle/destroyer name = "pulse destroyer" desc = "A heavy-duty, pulse-based energy weapon." - cell_type = "/obj/item/weapon/cell/infinite" + cell_type = "/obj/item/weapon/stock_parts/cell/infinite" attack_self(mob/living/user as mob) user << "\red [src.name] has three settings, and they are all DESTROY." - - -/obj/item/weapon/gun/energy/pulse_rifle/M1911 - name = "m1911-P" - desc = "It's not the size of the gun, it's the size of the hole it puts through people." - icon_state = "m1911-p" - cell_type = "/obj/item/weapon/cell/infinite" - w_class = 3.0 +/obj/item/weapon/gun/energy/pulse_rifle/carbine + name = "pulse carbine" + desc = "A compact variant of the pulse rifle with less firepower but easier storage." + w_class = 3 slot_flags = SLOT_BELT + icon_state = "pulse_carbine" + item_state = "pulse" + cell_type = "/obj/item/weapon/stock_parts/cell/pulse/carbine" + can_flashlight = 1 + + +/obj/item/weapon/gun/energy/pulse_rifle/pistol + name = "pulse pistol" + desc = "A pulse rifle in an easily concealed handgun package with low capacity." + w_class = 2 + slot_flags = SLOT_BELT + icon_state = "pulse_pistol" + item_state = "gun" + cell_type = "/obj/item/weapon/stock_parts/cell/pulse/pistol" + +/obj/item/weapon/gun/energy/pulse_rifle/pistol/m1911 + name = "\improper M1911-P" + desc = "A compact pulse core in a classic handgun frame for Nanotrasen officers. It's not the size of the gun, it's the size of the hole it puts through people." + icon_state = "m1911-p" + item_state = "gun" + cell_type = "/obj/item/weapon/stock_parts/cell/infinite" isHandgun() return 1 \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 04982e8e587..5e8a3a501f2 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -7,7 +7,7 @@ fire_sound = 'sound/weapons/Laser.ogg' origin_tech = "combat=2;magnets=4" w_class = 4.0 - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BACK projectile_type = "/obj/item/projectile/ion" @@ -92,7 +92,7 @@ item_state = "c20r" w_class = 4 projectile_type = "/obj/item/projectile/meteor" - cell_type = "/obj/item/weapon/cell/potato" + cell_type = "/obj/item/weapon/stock_parts/cell/potato" clumsy_check = 0 //Admin spawn only, might as well let clowns use it. var/charge_tick = 0 var/recharge_time = 5 //Time it takes for shots to recharge (in ticks) @@ -180,7 +180,7 @@ obj/item/weapon/gun/energy/staff/focus projectile_type = "/obj/item/projectile/beam/sniper" slot_flags = SLOT_BACK charge_cost = 2500 - fire_delay = 10 + fire_delay = 50 w_class = 4.0 var/zoom = 0 @@ -229,7 +229,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. projectile_type = "/obj/item/projectile/kinetic" fire_sound = 'sound/weapons/Kenetic_accel.ogg' charge_cost = 5000 - cell_type = "/obj/item/weapon/cell/crap" + cell_type = "/obj/item/weapon/stock_parts/cell/emproof" var/overheat = 0 var/recent_reload = 1 @@ -240,6 +240,9 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. recent_reload = 0 ..() +/obj/item/weapon/gun/energy/kinetic_accelerator/emp_act(severity) + return + /obj/item/weapon/gun/energy/kinetic_accelerator/attack_self(var/mob/living/user/L) if(overheat || recent_reload) return @@ -274,6 +277,11 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. silenced = 0 projectile_type = "/obj/item/projectile/energy/bolt/large" +/obj/item/weapon/gun/energy/kinetic_accelerator/crossbow/large/cyborg + desc = "One and done!" + icon_state = "crossbowlarge" + origin_tech = null + m_amt = 0 /obj/item/weapon/gun/energy/disabler name = "disabler" @@ -281,7 +289,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. icon_state = "disabler" item_state = null projectile_type = "/obj/item/projectile/beam/disabler" - cell_type = "/obj/item/weapon/cell" + cell_type = "/obj/item/weapon/stock_parts/cell" charge_cost = 500 /obj/item/weapon/gun/energy/disabler/cyborg @@ -326,7 +334,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. icon_state = "l6closed0" icon = 'icons/obj/gun.dmi' fire_sound = 'sound/weapons/Gunshot_smg.ogg' - cell_type = "/obj/item/weapon/cell/secborg" + cell_type = "/obj/item/weapon/stock_parts/cell/secborg" projectile_type = "/obj/item/projectile/bullet/midbullet3" charge_cost = 300 //Yeah, let's NOT give them a 300 round clip that recharges, 20 is more reasonable and will actually hurt the borg's battery for overuse. var/charge_tick = 0 diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm index cf3ba6028d6..998c15e2c01 100644 --- a/code/modules/projectiles/guns/energy/stun.dm +++ b/code/modules/projectiles/guns/energy/stun.dm @@ -6,7 +6,8 @@ item_state = null //so the human update icon uses the icon_state instead. fire_sound = 'sound/weapons/Taser.ogg' projectile_type = "/obj/item/projectile/energy/electrode" - cell_type = "/obj/item/weapon/cell/crap" + cell_type = "/obj/item/weapon/stock_parts/cell/crap" + fire_delay = 20 /obj/item/weapon/gun/energy/taser/cyborg name = "taser gun" @@ -14,7 +15,7 @@ icon_state = "taser" fire_sound = 'sound/weapons/Taser.ogg' projectile_type = "/obj/item/projectile/energy/electrode" - cell_type = "/obj/item/weapon/cell/secborg" + cell_type = "/obj/item/weapon/stock_parts/cell/secborg" var/charge_tick = 0 var/recharge_time = 10 //Time it takes for shots to recharge (in ticks) @@ -50,9 +51,9 @@ desc = "A high-tech revolver that fires internal, reusable stun cartidges in a revolving cylinder. Holds twice as much ammo as a standard taser." icon_state = "stunrevolver" fire_sound = "sound/weapons/gunshot.ogg" - origin_tech = "combat=3;materials=3;powerstorage=2" projectile_type = "/obj/item/projectile/energy/electrode" - cell_type = "/obj/item/weapon/cell" + cell_type = "/obj/item/weapon/stock_parts/cell" + fire_delay = 20 @@ -67,7 +68,7 @@ silenced = 1 fire_sound = 'sound/weapons/Genhit.ogg' projectile_type = "/obj/item/projectile/energy/bolt" - cell_type = "/obj/item/weapon/cell/crap" + cell_type = "/obj/item/weapon/stock_parts/cell/crap" var/charge_tick = 0 /obj/item/weapon/gun/energy/crossbow/New() diff --git a/code/modules/projectiles/guns/energy/temperature.dm b/code/modules/projectiles/guns/energy/temperature.dm index 520a2cf6c73..ffc680a151a 100644 --- a/code/modules/projectiles/guns/energy/temperature.dm +++ b/code/modules/projectiles/guns/energy/temperature.dm @@ -9,7 +9,7 @@ origin_tech = "combat=3;materials=4;powerstorage=3;magnets=2" projectile_type = "/obj/item/projectile/temp" - cell_type = "/obj/item/weapon/cell/crap" + cell_type = "/obj/item/weapon/stock_parts/cell/crap" New() diff --git a/code/modules/projectiles/guns/magic.dm b/code/modules/projectiles/guns/magic.dm index 9401783c54a..a874573aa25 100644 --- a/code/modules/projectiles/guns/magic.dm +++ b/code/modules/projectiles/guns/magic.dm @@ -5,7 +5,7 @@ icon_state = "staffofnothing" item_state = "staff" fire_sound = 'sound/weapons/emitter.ogg' - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT w_class = 5 var/projectile_type = "/obj/item/projectile/magic" var/max_charges = 6 diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index c45bb04a6b0..94d4869c5ec 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -24,18 +24,24 @@ return -/obj/item/weapon/gun/projectile/process_chambered() +/obj/item/weapon/gun/projectile/process_chambered(var/eject_casing = 1, var/empty_chamber = 1) // if(in_chamber) // return 1 var/obj/item/ammo_casing/AC = chambered //Find chambered round if(isnull(AC) || !istype(AC)) return 0 - AC.loc = get_turf(src) //Eject casing onto ground. - AC.SpinAnimation(10, 1) //next gen special effects - chambered = null + if(eject_casing) + AC.loc = get_turf(src) //Eject casing onto ground. + AC.SpinAnimation(10, 1) //next gen special effects + if(empty_chamber) + chambered = null chamber_round() if(AC.BB) + if(AC.reagents && AC.BB.reagents) + var/datum/reagents/casting_reagents = AC.reagents + casting_reagents.trans_to(AC.BB, casting_reagents.total_volume) //For chemical darts/bullets + casting_reagents.delete() in_chamber = AC.BB //Load projectile into chamber. AC.BB.loc = src //Set projectile loc to gun. AC.update_icon() @@ -52,7 +58,7 @@ return -/obj/item/weapon/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob) +/obj/item/weapon/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob, params) ..() if (istype(A, /obj/item/ammo_box/magazine)) var/obj/item/ammo_box/magazine/AM = A diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index 9371a09469a..e3c5ce80533 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -17,7 +17,7 @@ icon_state = "[initial(icon_state)][magazine ? "-[magazine.max_ammo]" : ""][chambered ? "" : "-e"][silenced ? "-suppressed" : ""]" return -/obj/item/weapon/gun/projectile/automatic/attackby(var/obj/item/A as obj, mob/user as mob) +/obj/item/weapon/gun/projectile/automatic/attackby(var/obj/item/A as obj, mob/user as mob, params) if(..() && chambered) alarmed = 0 @@ -103,7 +103,7 @@ user << "You remove the magazine from [src]." -/obj/item/weapon/gun/projectile/automatic/l6_saw/attackby(var/obj/item/A as obj, mob/user as mob) +/obj/item/weapon/gun/projectile/automatic/l6_saw/attackby(var/obj/item/A as obj, mob/user as mob, params) if(!cover_open && istype(A, mag_type)) user << "[src]'s cover is closed! You can't insert a new mag!" return @@ -174,11 +174,11 @@ else underbarrel.afterattack(target, user, flag, params) -/obj/item/weapon/gun/projectile/automatic/c90gl/attackby(var/obj/item/A, mob/user) +/obj/item/weapon/gun/projectile/automatic/c90gl/attackby(var/obj/item/A, mob/user, params) if(select) ..() else - underbarrel.attackby(A, user) + underbarrel.attackby(A, user, params) /obj/item/weapon/gun/projectile/automatic/c90gl/attack_self(var/mob/living/user) if(select) diff --git a/code/modules/projectiles/guns/projectile/crossbow.dm b/code/modules/projectiles/guns/projectile/crossbow.dm index 17fd65cacee..012f0f7dc3e 100644 --- a/code/modules/projectiles/guns/projectile/crossbow.dm +++ b/code/modules/projectiles/guns/projectile/crossbow.dm @@ -7,7 +7,6 @@ icon = 'icons/obj/weapons.dmi' icon_state = "bolt" item_state = "bolt" - flags = FPRINT | TABLEPASS throwforce = 8 w_class = 3.0 sharp = 1 @@ -72,7 +71,7 @@ var/tension = 0 // Current draw on the bow. var/max_tension = 5 // Highest possible tension. var/release_speed = 5 // Speed per unit of tension. - var/obj/item/weapon/cell/cell = null // Used for firing superheated rods. + var/obj/item/weapon/stock_parts/cell/cell = null // Used for firing superheated rods. var/current_user // Used to check if the crossbow has changed hands since being drawn. /obj/item/weapon/gun/launcher/crossbow/emp_act(severity) @@ -138,7 +137,7 @@ user.visible_message("[usr] draws back the string of [src]!","You continue drawing back the string of [src]!") spawn(25) increase_tension(user) -/obj/item/weapon/gun/launcher/crossbow/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/weapon/gun/launcher/crossbow/attackby(obj/item/W as obj, mob/user as mob, params) if(!in_chamber) if (istype(W,/obj/item/weapon/arrow)) user.drop_item() @@ -158,7 +157,7 @@ superheat_rod(user) return - if(istype(W, /obj/item/weapon/cell)) + if(istype(W, /obj/item/weapon/stock_parts/cell)) if(!cell) user.drop_item() W.loc = src @@ -196,7 +195,7 @@ /obj/item/weapon/gun/launcher/crossbow/french name = "french powered crossbow" -/obj/item/weapon/gun/launcher/crossbow/french/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/weapon/gun/launcher/crossbow/french/attackby(obj/item/W as obj, mob/user as mob, params) if(!in_chamber) if (istype(W,/obj/item/weapon/reagent_containers/food/snacks/baguette)) user.drop_item() @@ -213,7 +212,7 @@ user.visible_message("\The [src] only takes baguettes.") return - if(istype(W, /obj/item/weapon/cell)) + if(istype(W, /obj/item/weapon/stock_parts/cell)) user.visible_message("The [src] is too simple be adapted with a cell.") return @@ -256,7 +255,7 @@ if(4) usr << "It has a steel backbone, plastic lath and a cell mount installed." if(5) usr << "It has a steel cable loosely strung across the lath." -/obj/item/weapon/crossbowframe/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/weapon/crossbowframe/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W,/obj/item/stack/rods)) if(buildstate == 0) var/obj/item/stack/rods/R = W diff --git a/code/modules/projectiles/guns/projectile/grenade launcher.dm b/code/modules/projectiles/guns/projectile/grenade launcher.dm index 8833a63b280..d4b2c6fc167 100644 --- a/code/modules/projectiles/guns/projectile/grenade launcher.dm +++ b/code/modules/projectiles/guns/projectile/grenade launcher.dm @@ -4,7 +4,7 @@ desc = "A device that launches things." icon = 'icons/obj/weapons.dmi' w_class = 5.0 - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BACK var/release_force = 0 diff --git a/code/modules/projectiles/guns/projectile/launchers.dm b/code/modules/projectiles/guns/projectile/launchers.dm index d1d7e471f1b..fee2e2fef71 100644 --- a/code/modules/projectiles/guns/projectile/launchers.dm +++ b/code/modules/projectiles/guns/projectile/launchers.dm @@ -38,7 +38,7 @@ mag_type = "/obj/item/ammo_box/magazine/internal/cylinder/grenadelauncher" w_class = 3 -/obj/item/weapon/gun/projectile/revolver/grenadelauncher/attackby(var/obj/item/A, mob/user) +/obj/item/weapon/gun/projectile/revolver/grenadelauncher/attackby(var/obj/item/A, mob/user, params) ..() if(istype(A, /obj/item/ammo_box) || istype(A, /obj/item/ammo_casing)) chamber_round() diff --git a/code/modules/projectiles/guns/projectile/pneumatic.dm b/code/modules/projectiles/guns/projectile/pneumatic.dm index e3bcc5517a5..50f5d33d1e8 100644 --- a/code/modules/projectiles/guns/projectile/pneumatic.dm +++ b/code/modules/projectiles/guns/projectile/pneumatic.dm @@ -5,7 +5,7 @@ icon_state = "pneumatic" item_state = "pneumatic" w_class = 5.0 - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT fire_sound_text = "a loud whoosh of moving air" fire_delay = 50 fire_sound = 'sound/weapons/tablehit1.ogg' @@ -51,7 +51,7 @@ else usr << "There's no tank in [src]." -/obj/item/weapon/gun/launcher/pneumatic/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/weapon/gun/launcher/pneumatic/attackby(obj/item/W as obj, mob/user as mob, params) if(!tank && istype(W,/obj/item/weapon/tank)) user.drop_item() tank = W @@ -154,7 +154,7 @@ if(4) usr << "It has an outer chassis welded in place." if(5) usr << "It has a transfer valve installed." -/obj/item/weapon/cannonframe/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/weapon/cannonframe/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W,/obj/item/pipe)) if(buildstate == 0) user.drop_item() diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index d0dcee8fb2b..0879e11caf8 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -12,20 +12,9 @@ return /obj/item/weapon/gun/projectile/revolver/process_chambered() - var/obj/item/ammo_casing/AC = chambered //Find chambered round - if(isnull(AC) || !istype(AC)) - return 0 - chambered = null - chamber_round() - if(AC.BB) - in_chamber = AC.BB //Load projectile into chamber. - AC.BB.loc = src //Set projectile loc to gun. - AC.BB = null - AC.update_icon() - return 1 - return 0 + return ..(0, 1) -/obj/item/weapon/gun/projectile/revolver/attackby(var/obj/item/A as obj, mob/user as mob) +/obj/item/weapon/gun/projectile/revolver/attackby(var/obj/item/A as obj, mob/user as mob, params) var/num_loaded = 0 if(istype(A, /obj/item/ammo_box)) var/obj/item/ammo_box/AM = A @@ -126,7 +115,7 @@ M << "Your gun is now skinned as [choice]. Say hello to your new friend." return 1 -/obj/item/weapon/gun/projectile/revolver/detective/attackby(var/obj/item/A as obj, mob/user as mob) +/obj/item/weapon/gun/projectile/revolver/detective/attackby(var/obj/item/A as obj, mob/user as mob, params) ..() if(istype(A, /obj/item/weapon/screwdriver) || istype(A, /obj/item/weapon/conversion_kit)) if(magazine.caliber == "38") @@ -192,7 +181,7 @@ chamber_round() spun = 1 -/obj/item/weapon/gun/projectile/revolver/russian/attackby(var/obj/item/A as obj, mob/user as mob) +/obj/item/weapon/gun/projectile/revolver/russian/attackby(var/obj/item/A as obj, mob/user as mob, params) ..() user.visible_message("[user] spins the chamber of the revolver.", "You spin the revolver's chamber.") if(get_ammo() > 0) diff --git a/code/modules/projectiles/guns/projectile/rocket.dm b/code/modules/projectiles/guns/projectile/rocket.dm index 5f939e59073..8df666a62a4 100644 --- a/code/modules/projectiles/guns/projectile/rocket.dm +++ b/code/modules/projectiles/guns/projectile/rocket.dm @@ -8,7 +8,7 @@ throw_speed = 2 throw_range = 10 force = 5.0 - flags = FPRINT | TABLEPASS | CONDUCT | USEDELAY + flags = CONDUCT origin_tech = "combat=8;materials=5" projectile = /obj/item/missile var/missile_speed = 2 @@ -22,7 +22,7 @@ if (!(usr in view(2)) && usr!=src.loc) return usr << "\blue [rockets.len] / [max_rockets] rockets." -/obj/item/weapon/gun/rocketlauncher/attackby(obj/item/I as obj, mob/user as mob) +/obj/item/weapon/gun/rocketlauncher/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/ammo_casing/rocket)) if(rockets.len < max_rockets) user.drop_item() diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index 90436a500d0..c5c7eb6cc7c 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -5,14 +5,13 @@ item_state = "shotgun" w_class = 4.0 force = 10 - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BACK origin_tech = "combat=4;materials=2" var/recentpump = 0 // to prevent spammage - var/pumped = 0 mag_type = "/obj/item/ammo_box/magazine/internal/shot" -/obj/item/weapon/gun/projectile/shotgun/attackby(var/obj/item/A as obj, mob/user as mob) +/obj/item/weapon/gun/projectile/shotgun/attackby(var/obj/item/A as obj, mob/user as mob, params) var/num_loaded = 0 if(istype(A, /obj/item/ammo_box)) var/obj/item/ammo_box/AM = A @@ -36,21 +35,10 @@ /obj/item/weapon/gun/projectile/shotgun/process_chambered() - var/obj/item/ammo_casing/AC = chambered //Find chambered round - if(isnull(AC) || !istype(AC)) - return 0 - if(AC.BB) - if(AC.reagents && AC.BB.reagents) - var/datum/reagents/casting_reagents = AC.reagents - casting_reagents.trans_to(AC.BB, casting_reagents.total_volume) //For chemical darts - casting_reagents.delete() - in_chamber = AC.BB //Load projectile into chamber. - AC.BB.loc = src //Set projectile loc to gun. - AC.BB = null - AC.update_icon() - return 1 - return 0 + return ..(0, 0) +/obj/item/weapon/gun/projectile/shotgun/chamber_round() + return /obj/item/weapon/gun/projectile/shotgun/attack_self(mob/living/user as mob) if(recentpump) return @@ -63,24 +51,31 @@ /obj/item/weapon/gun/projectile/shotgun/proc/pump(mob/M as mob) playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1) - pumped = 0 + pump_unload(M) + pump_reload(M) + update_icon() //I.E. fix the desc + return 1 + +/obj/item/weapon/gun/projectile/shotgun/proc/pump_unload(mob/M) if(chambered)//We have a shell in the chamber chambered.loc = get_turf(src)//Eject casing chambered.SpinAnimation(5, 1) chambered = null if(in_chamber) in_chamber = null + +/obj/item/weapon/gun/projectile/shotgun/proc/pump_reload(mob/M) if(!magazine.ammo_count()) return 0 var/obj/item/ammo_casing/AC = magazine.get_round() //load next casing. chambered = AC - update_icon() //I.E. fix the desc - return 1 /obj/item/weapon/gun/projectile/shotgun/examine() ..() if (chambered) usr << "A [chambered.BB ? "live" : "spent"] one is in the chamber." +// COMBAT SHOTGUN // + /obj/item/weapon/gun/projectile/shotgun/combat name = "combat shotgun" desc = "A traditional shotgun with tactical furniture and an eight-shell capacity underneath." @@ -89,6 +84,8 @@ mag_type = "/obj/item/ammo_box/magazine/internal/shotcom" w_class = 5 +// RIOT SHOTGUN // + /obj/item/weapon/gun/projectile/shotgun/riot //for spawn in the armory name = "riot shotgun" desc = "A sturdy shotgun with a longer magazine and a fixed tactical stock designed for non-lethal riot control." @@ -96,11 +93,50 @@ mag_type = "/obj/item/ammo_box/magazine/internal/shotriot" sawn_desc = "Come with me if you want to live." -/obj/item/weapon/gun/projectile/shotgun/riot/attackby(var/obj/item/A as obj, mob/user as mob) +/obj/item/weapon/gun/projectile/shotgun/riot/attackby(var/obj/item/A as obj, mob/user as mob, params) ..() if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/melee/energy) || istype(A, /obj/item/weapon/pickaxe/plasmacutter)) sawoff(user) + +/////////////////////// +// BOLT ACTION RIFLE // +/////////////////////// + +/obj/item/weapon/gun/projectile/shotgun/boltaction + name = "bolt action rifle" + desc = "This piece of junk looks like something that could have been used 700 years ago." + icon_state = "moistnugget" + item_state = "moistnugget" + icon_override = 'icons/mob/in-hand/guns.dmi' + slot_flags = 0 //no SLOT_BACK sprite, alas + mag_type = "/obj/item/ammo_box/magazine/internal/boltaction" + var/bolt_open = 0 + +/obj/item/weapon/gun/projectile/shotgun/boltaction/pump(mob/M) + playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1) + if(bolt_open) + pump_reload(M) + else + pump_unload(M) + bolt_open = !bolt_open + update_icon() //I.E. fix the desc + return 1 + +/obj/item/weapon/gun/projectile/shotgun/boltaction/attackby(var/obj/item/A as obj, mob/user as mob) + if(!bolt_open) + user << "The bolt is closed!" + return + . = ..() + +/obj/item/weapon/gun/projectile/shotgun/boltaction/examine(mob/user) + ..() + user << "The bolt is [bolt_open ? "open" : "closed"]." + +///////////////////////////// +// DOUBLE BARRELED SHOTGUN // +///////////////////////////// + /obj/item/weapon/gun/projectile/revolver/doublebarrel name = "double-barreled shotgun" desc = "A true classic." @@ -108,13 +144,13 @@ item_state = "shotgun" w_class = 4.0 force = 10 - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BACK origin_tech = "combat=3;materials=1" mag_type = "/obj/item/ammo_box/magazine/internal/cylinder/dualshot" sawn_desc = "Omar's coming!" -/obj/item/weapon/gun/projectile/revolver/doublebarrel/attackby(var/obj/item/A as obj, mob/user as mob) +/obj/item/weapon/gun/projectile/revolver/doublebarrel/attackby(var/obj/item/A as obj, mob/user as mob, params) ..() if(istype(A, /obj/item/ammo_box) || istype(A, /obj/item/ammo_casing)) chamber_round() @@ -163,16 +199,16 @@ item_state = "shotgun" w_class = 4.0 force = 10 + slot_flags = null origin_tech = "combat=2;materials=2" mag_type = "/obj/item/ammo_box/magazine/internal/cylinder/improvised" sawn_desc = "I'm just here for the gasoline." -/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/attackby(var/obj/item/A as obj, mob/user as mob) +/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/attackby(var/obj/item/A as obj, mob/user as mob, params) ..() if(istype(A, /obj/item/stack/cable_coil)) var/obj/item/stack/cable_coil/C = A if(C.use(10)) - flags = CONDUCT slot_flags = SLOT_BACK icon_state = "ishotgunsling" user << "You tie the lengths of cable to the shotgun, making a sling." diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 5f5eef7c03d..af9d5338d42 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -16,7 +16,6 @@ density = 1 unacidable = 1 anchored = 1 //There's a reason this is here, Mport. God fucking damn it -Agouri. Find&Fix by Pete. The reason this is here is to stop the curving of emitter shots. - flags = FPRINT | TABLEPASS pass_flags = PASSTABLE mouse_opacity = 0 hitsound = 'sound/weapons/pierce.ogg' @@ -76,7 +75,7 @@ proj_hit = 1 qdel(src) - proc/on_hit(var/atom/target, var/blocked = 0) + proc/on_hit(var/atom/target, var/blocked = 0, var/hit_zone) if(!isliving(target)) return 0 if(isanimal(target)) return 0 var/mob/living/L = target @@ -108,6 +107,12 @@ loc = A.loc return 0// nope.avi + var/reagent_note + if(reagents && reagents.reagent_list) + reagent_note = " REAGENTS:" + for(var/datum/reagent/R in reagents.reagent_list) + reagent_note += R.id + " (" + reagent_note += num2text(R.volume) + ") " //Lower accurancy/longer range tradeoff. Distance matters a lot here, so at // close distance, actually RAISE the chance to hit. var/distance = get_dist(get_turf(A), starting) // Get the distance between the turf shot from and the mob we hit and use that for the calculations. @@ -125,18 +130,18 @@ playsound(loc, hitsound, 20, 1, -1) visible_message("\red [A.name] is hit by the [src.name] in the [parse_zone(def_zone)]!")//X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter if(istype(firer, /mob)) - M.attack_log += "\[[time_stamp()]\] [firer]/[firer.ckey] shot [M]/[M.ckey] with a [src.type]" - firer.attack_log += "\[[time_stamp()]\] [firer]/[firer.ckey] shot [M]/[M.ckey] with a [src.type]" + M.attack_log += "\[[time_stamp()]\] [firer]/[firer.ckey] shot [M]/[M.ckey] with a [src.type][reagent_note]" + firer.attack_log += "\[[time_stamp()]\] [firer]/[firer.ckey] shot [M]/[M.ckey] with a [src.type][reagent_note]" if(M.ckey && chatlog_attacks) - msg_admin_attack("[firer] ([firer.ckey]) shot [M] ([M.ckey]) with a [src] (JMP)") //BS12 EDIT ALG + msg_admin_attack("[firer] ([firer.ckey]) shot [M] ([M.ckey]) with a [src][reagent_note] (JMP)") //BS12 EDIT ALG if(!iscarbon(firer)) M.LAssailant = null else M.LAssailant = firer else - M.attack_log += "\[[time_stamp()]\] UNKNOWN SUBJECT (No longer exists) shot [M]/[M.ckey] with a [src]" + M.attack_log += "\[[time_stamp()]\] UNKNOWN SUBJECT (No longer exists) shot [M]/[M.ckey] with a [src][reagent_note]" if(M.ckey && chatlog_attacks) - msg_admin_attack("UNKNOWN shot [M] ([M.ckey]) with a [src] (JMP)") //BS12 EDIT ALG + msg_admin_attack("UNKNOWN shot [M] ([M.ckey]) with a [src][reagent_note] (JMP)") //BS12 EDIT ALG spawn(0) if(A) diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 0c8fb7ec0fe..0cf1a336331 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -144,6 +144,8 @@ name = "dart" icon_state = "cbbolt" damage = 6 + embed = 0 + sharp = 0 New() ..() diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm index 1cb70a29513..60043e07933 100644 --- a/code/modules/projectiles/projectile/energy.dm +++ b/code/modules/projectiles/projectile/energy.dm @@ -25,6 +25,12 @@ sparks.set_up(1, 1, src) sparks.start() proj_hit = 1 + else if(iscarbon(target)) + var/mob/living/carbon/C = target + if(HULK in C.mutations) + C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) + else if(C.status_flags & CANWEAKEN) + C.do_jitter_animation(jitter) ..() /obj/item/projectile/energy/electrode/on_range() //to ensure the bolt sparks when it reaches the end of its range if it didn't hit a target yet diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index e2e643a1111..f143e5bbcdb 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -205,4 +205,9 @@ obj/item/projectile/kinetic/New() /obj/item/effect/kinetic_blast/New() spawn(4) - del(src) \ No newline at end of file + del(src) + +/obj/item/projectile/bullet/frag12 + name ="explosive slug" + damage = 25 + weaken = 5 diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/Chemistry-Holder.dm index e8e27bba046..51cb5012af4 100644 --- a/code/modules/reagents/Chemistry-Holder.dm +++ b/code/modules/reagents/Chemistry-Holder.dm @@ -398,11 +398,12 @@ datum return 1 check_gofast(var/mob/M) - if(istype(M, /mob)) - if(M.reagents.has_reagent("hyperzine")||M.reagents.has_reagent("nuka_cola")) - return 1 - else - M.status_flags &= ~GOTTAGOFAST + if(M && istype(M, /mob)) + if(M.reagents) + if(M.reagents.has_reagent("hyperzine")||M.reagents.has_reagent("nuka_cola")) + return 1 + else + M.status_flags &= ~GOTTAGOFAST update_total() total_volume = 0 @@ -640,3 +641,10 @@ datum atom/proc/create_reagents(var/max_vol) reagents = new/datum/reagents(max_vol) reagents.my_atom = src + +/datum/reagents/Destroy() + for(var/datum/reagent/reagent in reagent_list) + reagent.Destroy() + + if(my_atom) + my_atom = null \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index f9aa75afee5..c992e972fa5 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -26,6 +26,7 @@ var/list/broken_requirements = list() var/broken_on_spawn = 0 var/recharge_delay = 15 + var/image/icon_beaker = null //cached overlay /obj/machinery/chem_dispenser/proc/recharge() @@ -59,13 +60,14 @@ dispensable_reagents = sortList(dispensable_reagents) if(broken_on_spawn) + overlays.Cut() var/amount = pick(3,3,4) var/list/options = list() options[/obj/item/weapon/stock_parts/capacitor/adv] = "Add an advanced capacitor to fix it." options[/obj/item/weapon/stock_parts/console_screen] = "Replace the console screen to fix it." options[/obj/item/weapon/stock_parts/manipulator/pico] = "Upgrade to a pico manipulator to fix it." options[/obj/item/weapon/stock_parts/matter_bin/super] = "Give it a super matter bin to fix it." - options[/obj/item/weapon/cell/super] = "Replace the reagent synthesizer with a super capacity cell to fix it." + options[/obj/item/weapon/stock_parts/cell/super] = "Replace the reagent synthesizer with a super capacity cell to fix it." options[/obj/item/device/mass_spectrometer/adv] = "Replace the reagent scanner with an advanced mass spectrometer to fix it" options[/obj/item/weapon/stock_parts/micro_laser/high] = "Repair the reagent synthesizer with an high-power micro-laser to fix it" options[/obj/item/device/reagent_scanner/adv] = "Replace the reagent scanner with an advanced reagent scanner to fix it" @@ -181,12 +183,11 @@ var/obj/item/weapon/reagent_containers/glass/B = beaker B.loc = loc beaker = null - if(!panel_open) - icon_state = initial(icon_state) + overlays.Cut() add_fingerprint(usr) return 1 // update UIs attached to this object -/obj/machinery/chem_dispenser/attackby(var/obj/item/weapon/reagent_containers/B as obj, var/mob/user as mob) +/obj/machinery/chem_dispenser/attackby(var/obj/item/weapon/reagent_containers/B as obj, var/mob/user as mob, params) if(isrobot(user)) return @@ -211,10 +212,13 @@ B.loc = src user << "You set [B] on the machine." nanomanager.update_uis(src) // update all UIs attached to src - icon_state = "[initial(icon_state)]2" + if(!icon_beaker) + icon_beaker = image('icons/obj/chemical.dmi', src, "disp_beaker") //randomize beaker overlay position. + icon_beaker.pixel_x = rand(-10,5) + overlays += icon_beaker return -/obj/machinery/chem_dispenser/attackby(var/obj/item/weapon/B as obj, var/mob/user as mob) +/obj/machinery/chem_dispenser/attackby(var/obj/item/weapon/B as obj, var/mob/user as mob, params) ..() if(istype(B, /obj/item/device/multitool)) if(hackedcheck == 0) @@ -290,7 +294,7 @@ component_parts += new /obj/item/weapon/stock_parts/manipulator(src) component_parts += new /obj/item/weapon/stock_parts/capacitor(src) component_parts += new /obj/item/weapon/stock_parts/console_screen(src) - component_parts += new /obj/item/weapon/cell/super(src) + component_parts += new /obj/item/weapon/stock_parts/cell/super(src) RefreshParts() /obj/machinery/chem_dispenser/constructable/RefreshParts() @@ -303,14 +307,14 @@ max_energy = temp_energy * 5 //max energy = (bin1.rating + bin2.rating - 1) * 5, 5 on lowest 25 on highest for(var/obj/item/weapon/stock_parts/capacitor/C in component_parts) time += C.rating - for(var/obj/item/weapon/cell/P in component_parts) + for(var/obj/item/weapon/stock_parts/cell/P in component_parts) time += round(P.maxcharge, 10000) / 10000 recharge_delay /= time/2 //delay between recharges, double the usual time on lowest 50% less than usual on highest for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) for(i=1, i<=M.rating, i++) dispensable_reagents = sortList(dispensable_reagents | special_reagents[i]) -/obj/machinery/chem_dispenser/constructable/attackby(var/obj/item/I, var/mob/user) +/obj/machinery/chem_dispenser/constructable/attackby(var/obj/item/I, var/mob/user, params) if(istype(I, /obj/item/weapon/reagent_containers/glass)) if(panel_open) user << "Close the maintenance panel first." @@ -396,7 +400,7 @@ spawn(rand(0, 15)) stat |= NOPOWER -/obj/machinery/chem_master/attackby(var/obj/item/weapon/B as obj, var/mob/user as mob) +/obj/machinery/chem_master/attackby(var/obj/item/weapon/B as obj, var/mob/user as mob, params) if(istype(B, /obj/item/weapon/reagent_containers/glass) || istype(B, /obj/item/weapon/reagent_containers/food/drinks/drinkingglass)) @@ -440,7 +444,7 @@ usr << browse(null, "window=chemmaster") usr.unset_machine() return - + if (href_list["print_p"]) if (!(src.printing)) src.printing = 1 @@ -465,7 +469,7 @@ P.info += "

Notes:
" P.name = "Chemical Analysis - [href_list["name"]]" src.printing = null - + if(beaker) var/datum/reagents/R = beaker:reagents if (href_list["analyze"]) @@ -929,7 +933,7 @@ return -/obj/machinery/computer/pandemic/attackby(var/obj/I as obj, var/mob/user as mob) +/obj/machinery/computer/pandemic/attackby(var/obj/I as obj, var/mob/user as mob, params) if(istype(I, /obj/item/weapon/reagent_containers/glass)) if(stat & (NOPOWER|BROKEN)) return if(src.beaker) @@ -1026,7 +1030,7 @@ return -/obj/machinery/reagentgrinder/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/machinery/reagentgrinder/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if (istype(O,/obj/item/weapon/reagent_containers/glass) || \ @@ -1069,7 +1073,7 @@ user << "Cannot refine into a reagent." return 1 - user.before_take_item(O) + user.unEquip(O) O.loc = src holdingitems += O src.updateUsrDialog() diff --git a/code/modules/reagents/Chemistry-Reagents-Recreational.dm b/code/modules/reagents/Chemistry-Reagents-Recreational.dm deleted file mode 100644 index 91708e674ba..00000000000 --- a/code/modules/reagents/Chemistry-Reagents-Recreational.dm +++ /dev/null @@ -1,158 +0,0 @@ -//Cough medicine. -/datum/reagent/antidepressant/dextromethorphan - name = "Dextromethorphan" - id = "dextromethorphan" - description = "Cough medicine." - reagent_state = LIQUID - color = "#FF1111" - custom_metabolism = 0.05 - data = 0 - var/message = 0 - - on_mob_life(var/mob/living/M as mob) - if(!M) M = holder.my_atom - if(!data) data = 0 - if(!message) message = 0 - data += custom_metabolism - switch(data + src.volume) - if(1 to 5) - if(message == 0) - M << "\red Your throat feels better and you stop coughing." - //The coughing check is made in carbon/human/emote.dm where it checks after this reagent. - message = 1 - if(5 to 12.5) - if(message < 2) - M << "\red You feel full of strength and energy! You're getting restless!" - message = 2 - if(prob(5)) M.emote(pick("twitch_s")) - if(12.5 to 25) - if(message < 3) - M << "\red Your heartrate is racing. You feel euphoric!" - message = 3 - M.druggy = max(M.druggy, 15) - if(prob(5)) M.emote(pick("twitch_s","moan")) - if(25 to INFINITY) - if(message < 4) - M << "\red Your heart is racing and your body won't respond properly. You almost feel like you're on autopilot." - message = 4 - M.druggy = max(M.druggy, 15) - if(prob(10)) M.emote(pick("twitch","moan","drool")) - if(prob(10)) M:weakened = max(M:weakened, 10) - if(prob(5)) M.hallucination = max(M.hallucination, 5) - - ..() - return - -/datum/chemical_reaction/dextromethorphan - name = "Dextromethorphan" - id = "dextromethorphan" - result = "dextromethorphan" - required_reagents = list("cryptobiolin" = 1, "hydrogen" = 1, "carbon" = 1) - result_amount = 3 - -//MDMA -/datum/reagent/antidepressant/mdma - name = "MDMA" - id = "mdma" - description = "MDMA is one of the most popular recreational psychoactives, most commonly sold in the form of 'ecstasy' tablets. It is known for its empathogenic, euphoric, and stimulant effects, and has also been used in psychotherapy." - reagent_state = LIQUID - color = "#EEEEEE" - custom_metabolism = 0.1 - data = 0 - var/message = 0 - - on_mob_life(var/mob/living/M as mob) - if(!M) M = holder.my_atom - if(!data) data = 0 - if(!message) message = 0 - data += custom_metabolism - switch(data + src.volume) - if(1 to 5) - if(message == 0) - M << "\red Your heart rate increases. Your senses all seem more amplified. You start to feel... euphoric." - message = 1 - M.druggy = max(M.druggy, 15) - if(prob(5)) M.emote(pick("giggle","moan")) - if(5 to 10) - if(message < 2) - M << "\red Your heart rate increases. Your senses all seem more amplified. You start to feel... euphoric." - message = 2 - M.druggy = max(M.druggy, 15) - if(prob(5)) M.emote(pick("giggle","moan")) - if(10 to 20) - if(message < 3) - M << "\red Your heart rate increases. Your senses all seem more amplified. You start to feel... euphoric." - message = 3 - M.druggy = max(M.druggy, 15) - if(prob(5)) M.emote(pick("giggle","moan")) - if(20 to INFINITY) - if(message < 4) - M << "\red That was probably too much..." - message = 4 - M.druggy = max(M.druggy, 15) - if(prob(10)) M.emote(pick("twitch","giggle","moan")) - if(prob(10)) M.emote(pick("drool")) - if(prob(10)) M:weakened = max(M:weakened, 10) - ..() - return - -/datum/chemical_reaction/mdma - name = "MDMA" - id = "mdma" - result = "mdma" - required_reagents = list("cryptobiolin" = 1, "inaprovaline" = 1, "sugar" = 1) - result_amount = 3 - -//Meth -/datum/reagent/antidepressant/meth - name = "Methamphetamine" - id = "meth" - description = "Methamphetamine is a neurotoxin and potent psychostimulant of the phenethylamine and amphetamine classes that is used as a recreational drug and, rarely, to treat attention deficit hyperactivity disorder (ADHD) and obesity." - reagent_state = LIQUID - color = "#000088" - custom_metabolism = 0.1 - data = 0 - var/message = 0 - - on_mob_life(var/mob/living/M as mob) - if(!M) M = holder.my_atom - if(!data) data = 0 - if(!message) message = 0 - data += custom_metabolism - switch(data + src.volume) - if(1 to 5) - if(message == 0) - M << "\red You feel an intense euphoria wash over you." - message = 1 - M.druggy = max(M.druggy, 15) - if(prob(10)) M.emote(pick("giggle","moan")) - if(5 to 10) - if(message < 2) - M << "\red The euphoria washing over you is accompanied by an intense restlessness. You need something to do... badly." - message = 2 - M.druggy = max(M.druggy, 15) - if(prob(10)) M.emote(pick("giggle", "moan", "twitch_s", "twitch")) - if(10 to 20) - if(message < 3) - M << "\red The euphoria you're feeling is accompanied by equal parts restlessness and discomfort as your heartbeat goes all over the place." - message = 3 - M.druggy = max(M.druggy, 15) - if(prob(10)) M.emote(pick("giggle", "moan", "twitch_s", "twitch")) - if(20 to INFINITY) - if(message < 4) - M << "\red Your heartbeat becomes highly irregular all of a sudden. The world seems a blur around you. Your head is aching." - message = 4 - M.druggy = max(M.druggy, 15) - if(prob(10)) M.emote(pick("giggle", "moan", "twitch_s", "twitch")) - if(prob(10)) M.emote(pick("drool")) - if(prob(10)) M:weakened = max(M:weakened, 10) - ..() - return - -/datum/chemical_reaction/meth - name = "Methamphetamine" - id = "meth" - result = "meth" - required_reagents = list("water" = 1, "dextromethorphan" = 1, "potassium" = 1) - required_catalysts = list("fuel" = 5) - result_amount = 3 \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index 5de47de26d8..266895d0d53 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -210,6 +210,7 @@ datum description = "A ubiquitous chemical substance that is composed of hydrogen and oxygen." reagent_state = LIQUID color = "#0064C8" // rgb: 0, 100, 200 + var/cooling_temperature = 2 reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume) if(!istype(M, /mob/living)) @@ -224,6 +225,7 @@ datum reaction_turf(var/turf/simulated/T, var/volume) if (!istype(T)) return + var/CT = cooling_temperature src = null if(volume >= 3) if(T.wet >= 1) return @@ -248,10 +250,10 @@ datum var/hotspot = (locate(/obj/fire) in T) if(hotspot && !istype(T, /turf/space)) var/datum/gas_mixture/lowertemp = T.remove_air( T:air:total_moles() ) - lowertemp.temperature = max( min(lowertemp.temperature-2000,lowertemp.temperature / 2) ,0) + lowertemp.temperature = max( min(lowertemp.temperature-(CT*1000),lowertemp.temperature / CT) ,0) lowertemp.react() T.assume_air(lowertemp) - del(hotspot) + qdel(hotspot) return reaction_obj(var/obj/O, var/volume) @@ -398,7 +400,7 @@ datum on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom - if (M_FAT in M.mutations) + if (FAT in M.mutations) M.gib() ..() return @@ -483,38 +485,6 @@ datum ..() return - srejuvenate - name = "Soporific Rejuvenant" - id = "stoxin2" - description = "Put people to sleep, and heals them." - reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 - on_mob_life(var/mob/living/M as mob) - if(!M) M = holder.my_atom - if(!data) data = 1 - data++ - if(M.losebreath >= 10) - M.losebreath = max(10, M.losebreath-10) - holder.remove_reagent(src.id, 0.2) - switch(data) - if(1 to 15) - M.eye_blurry = max(M.eye_blurry, 10) - if(15 to 25) - M.drowsyness = max(M.drowsyness, 20) - if(25 to INFINITY) - M.sleeping += 1 - M.adjustOxyLoss(-M.getOxyLoss()) - M.SetWeakened(0) - M.SetStunned(0) - M.SetParalysis(0) - M.dizziness = 0 - M.drowsyness = 0 - M.stuttering = 0 - M.confused = 0 - M.jitteriness = 0 - ..() - return - inaprovaline name = "Inaprovaline" id = "inaprovaline" @@ -1010,7 +980,7 @@ datum if(prob(50)) M.apply_effect(50,IRRADIATE,0) // curing it that way may kill you instead M.adjustToxLoss(100) - M:antibodies |= V.antigen + C.antibodies |= V.antigen ..() return @@ -1035,24 +1005,12 @@ datum var/needs_update = 1 //M.mutations.len > 0 - //Ryetalyn now cures by a random chance per on_mob_life call - Bone White - // 1 volume = ~2% chance - // 10 volume = ~17% chance - // 30 volume = ~38% chance - //if (rand(0, 50+volume) > 50 && ishuman(M)) - if (volume >= 1 && ishuman(M)) - for(var/block=1;block<=DNA_SE_LENGTH;block++) - M.dna.SetSEState(block,0) - genemutcheck(M,block,null,MUTCHK_FORCED) - M.update_mutations() + for(var/block=1;block<=DNA_SE_LENGTH;block++) + M.dna.SetSEState(block,0) + genemutcheck(M,block,null,MUTCHK_FORCED) + M.update_mutations() - M.dna.struc_enzymes = M.dna.struc_enzymes_original - - /* Old Code (non-functional) - M.mutations = list() - M.disabilities = 0 - M.sdisabilities = 0 - */ + M.dna.struc_enzymes = M.dna.struc_enzymes_original // Might need to update appearance for hulk etc. if(needs_update && ishuman(M)) @@ -1433,6 +1391,13 @@ datum H.adjustToxLoss(50) ..() return + if(ismonkey(M)) + var/mob/living/carbon/monkey/MO = M + if(MO.dna) + if(MO.dna.mutantrace == "plant") //plantmen monkeys (diona) take EVEN MORE damage + MO.adjustToxLoss(100) + ..() + return plasma name = "Plasma" @@ -1628,25 +1593,6 @@ datum ..() return - Alchdranine - name = "Alchdranine" - id = "alchdranine" - description = "Alchdranine is an extremely strange chemical substance that can be used to treat almost any injury with a high level of effectiveness " - reagent_state = LIQUID - color = "#07a4d1" // rgb: 7, 164, 209 - - on_mob_life(var/mob/living/M as mob, var/alien) - if(M.stat == 2.0) - return - if(!M) M = holder.my_atom - if(!alien || alien != IS_DIONA) - M.adjustOxyLoss(-1*REM) - M.heal_organ_damage(1*REM,0) - M.heal_organ_damage(0,1*REM) - M.adjustToxLoss(-1*REM) - ..() - return - adminordrazine //An OP chemical for admins name = "Adminordrazine" id = "adminordrazine" @@ -1656,43 +1602,20 @@ datum on_mob_life(var/mob/living/carbon/M as mob) if(!M) M = holder.my_atom ///This can even heal dead people. + for(var/datum/reagent/R in M.reagents.reagent_list) + if(R != src) + M.reagents.remove_reagent(R.id,5) M.setCloneLoss(0) M.setOxyLoss(0) M.radiation = 0 M.heal_organ_damage(5,5) M.adjustToxLoss(-5) - if(holder.has_reagent("toxin")) - holder.remove_reagent("toxin", 5) - if(holder.has_reagent("stoxin")) - holder.remove_reagent("stoxin", 5) - if(holder.has_reagent("plasma")) - holder.remove_reagent("plasma", 5) - if(holder.has_reagent("sacid")) - holder.remove_reagent("sacid", 5) - if(holder.has_reagent("pacid")) - holder.remove_reagent("pacid", 5) - if(holder.has_reagent("cyanide")) - holder.remove_reagent("cyanide", 5) - if(holder.has_reagent("lexorin")) - holder.remove_reagent("lexorin", 5) - if(holder.has_reagent("amatoxin")) - holder.remove_reagent("amatoxin", 5) - if(holder.has_reagent("chloralhydrate")) - holder.remove_reagent("chloralhydrate", 5) - if(holder.has_reagent("carpotoxin")) - holder.remove_reagent("carpotoxin", 5) - if(holder.has_reagent("zombiepowder")) - holder.remove_reagent("zombiepowder", 5) - if(holder.has_reagent("mindbreaker")) - holder.remove_reagent("mindbreaker", 5) M.hallucination = 0 M.setBrainLoss(0) M.disabilities = 0 M.sdisabilities = 0 M.eye_blurry = 0 M.eye_blind = 0 -// M.disabilities &= ~NEARSIGHTED //doesn't even do anythig cos of the disabilities = 0 bit -// M.sdisabilities &= ~BLIND //doesn't even do anythig cos of the sdisabilities = 0 bit if(ishuman(M)) var/mob/living/carbon/human/H = M var/datum/organ/internal/eyes/E = H.internal_organs_by_name["eyes"] @@ -1705,12 +1628,25 @@ datum M.dizziness = 0 M.drowsyness = 0 M.stuttering = 0 + M.slurring = 0 M.confused = 0 M.sleeping = 0 M.jitteriness = 0 + if(istype(M,/mob/living/carbon)) // make sure to only use it on carbon mobs + var/mob/living/carbon/C = M + if(C.virus2.len) + for (var/ID in C.virus2) + var/datum/disease2/disease/V = C.virus2[ID] + C.antibodies |= V.antigen ..() return + nanites + name = "Nanites" + id = "nanites" + description = "Nanomachines that aid in rapid cellular regeneration." + + synaptizine name = "Synaptizine" id = "synaptizine" @@ -2121,47 +2057,7 @@ datum description = "A highly addictive stimulant extracted from the tobacco plant." reagent_state = LIQUID color = "#181818" // rgb: 24, 24, 24 -/* - ethanol - name = "Ethanol" - id = "ethanol" - description = "A well-known alcohol with a variety of applications." - reagent_state = LIQUID - color = "#404030" // rgb: 64, 64, 48 - on_mob_life(var/mob/living/M as mob) - if(!data) data = 1 - data++ - M.Dizzy(5) - M.jitteriness = max(M.jitteriness-5,0) - if(data >= 25) - if (!M.stuttering) M.stuttering = 1 - M.stuttering += 4 - if(data >= 40 && prob(33)) - if (!M.confused) M.confused = 1 - M.confused += 3 - ..() - return - reaction_obj(var/obj/O, var/volume) - if(istype(O,/obj/item/weapon/paper)) - var/obj/item/weapon/paper/paperaffected = O - paperaffected.clearpaper() - usr << "The solution melts away the ink on the paper." - if(istype(O,/obj/item/weapon/book)) - if(volume >= 5) - var/obj/item/weapon/book/affectedbook = O - affectedbook.dat = null - usr << "The solution melts away the ink on the book." - else - usr << "It wasn't enough..." - return - reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume)//Splashing people with ethanol isn't quite as good as fuel. - if(!istype(M, /mob/living)) - return - if(method == TOUCH) - M.adjust_fire_stacks(volume / 15) - return -*/ ammonia name = "Ammonia" id = "ammonia" @@ -2169,11 +2065,6 @@ datum reagent_state = GAS color = "#404030" // rgb: 64, 64, 48 - ultraglue - name = "Ultra Glue" - id = "glue" - description = "An extremely powerful bonding agent." - color = "#FFFFCC" // rgb: 255, 255, 204 diethylamine name = "Diethylamine" @@ -2239,71 +2130,26 @@ datum ..() return - beer2 //copypasta of chloral hydrate, disguised as normal beer for use by emagged brobots + beer2 //disguised as normal beer for use by emagged brobots name = "Beer" id = "beer2" description = "An alcoholic beverage made from malted grains, hops, yeast, and water." - reagent_state = LIQUID color = "#664300" // rgb: 102, 67, 0 - reaction_mob(var/mob/living/carbon/M, var/method=TOUCH, var/volume) - if(!..()) return - if(!istype(M) || !M.dna) return //No robots, AIs, aliens, Ians or other mobs should be affected by this. - src = null - if((method==TOUCH && prob(33)) || method==INGEST) - randmuti(M) - if(prob(98)) randmutb(M) - else randmutg(M) - domutcheck(M, null) - M.UpdateAppearance() - return - on_mob_life(var/mob/living/carbon/M) - if(!istype(M)) return - if(!M) M = holder.my_atom - M.apply_effect(10,IRRADIATE,0) + on_mob_life(var/mob/living/M as mob) + if(!data) + data = 1 + switch(data) + if(1 to 50) + M.sleeping += 1 + if(51 to INFINITY) + M.sleeping += 1 + M.adjustToxLoss((data - 50)*REM) + data++ + holder.remove_reagent(src.id, 0.5 * REAGENTS_METABOLISM) ..() return - - potassium_chloride - name = "Potassium Chloride" - id = "potassium_chloride" - description = "A delicious salt that stops the heart when injected into cardiac muscle." - reagent_state = SOLID - color = "#FFFFFF" // rgb: 255,255,255 - overdose = 30 - - on_mob_life(var/mob/living/carbon/M as mob) - var/mob/living/carbon/human/H = M - if(H.stat != 1) - if (volume >= overdose) - if(H.losebreath >= 10) - H.losebreath = max(10, H.losebreath-10) - H.adjustOxyLoss(2) - H.Weaken(10) - ..() - return - - potassium_chlorophoride - name = "Potassium Chlorophoride" - id = "potassium_chlorophoride" - description = "A specific chemical based on Potassium Chloride to stop the heart for surgery. Not safe to eat!" - reagent_state = SOLID - color = "#FFFFFF" // rgb: 255,255,255 - overdose = 20 - - on_mob_life(var/mob/living/carbon/M as mob) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(H.stat != 1) - if(H.losebreath >= 10) - H.losebreath = max(10, M.losebreath-10) - H.adjustOxyLoss(2) - H.Weaken(10) - ..() - return - - /////////////////////////Food Reagents//////////////////////////// // Part of the food code. Nutriment is used instead of the old "heal_amt" code. Also is where all the food // condiments, additives, and such go. @@ -2319,19 +2165,6 @@ datum if(!M) M = holder.my_atom if(prob(50)) M.heal_organ_damage(1,0) M.nutrition += nutriment_factor // For hunger and fatness -/* - // If overeaten - vomit and fall down - // Makes you feel bad but removes reagents and some effect - // from your body - if (M.nutrition > 650) - M.nutrition = rand (250, 400) - M.weakened += rand(2, 10) - M.jitteriness += rand(0, 5) - M.dizziness = max (0, (M.dizziness - rand(0, 15))) - M.druggy = max (0, (M.druggy - rand(0, 15))) - M.adjustToxLoss(rand(-15, -5))) - M.updatehealth() -*/ ..() return @@ -2562,15 +2395,16 @@ datum return Del() - if (istype(holder.my_atom,/mob/living)) - var/mob/living/M as mob - var/to_remove = 0 - if (holder.has_reagent("anti_toxin")) - to_remove = min(holder.get_reagent_amount("anti_toxin"),data) - holder.remove_reagent("anti_toxin", to_remove, 0) - data -= to_remove - if(M) - M.adjustToxLoss((data-1)*rand(2,4)) + if(holder) + if (istype(holder.my_atom,/mob/living)) + var/mob/living/M as mob + var/to_remove = 0 + if (holder.has_reagent("anti_toxin")) + to_remove = min(holder.get_reagent_amount("anti_toxin"),data) + holder.remove_reagent("anti_toxin", to_remove, 0) + data -= to_remove + if(M) + M.adjustToxLoss((data-1)*rand(2,4)) ..() psilocybin @@ -2622,25 +2456,6 @@ datum return ..() -/* //removed because of meta bullshit. this is why we can't have nice things. - syndicream - name = "Cream filling" - id = "syndicream" - description = "Delicious cream filling of a mysterious origin. Tastes criminally good." - nutriment_factor = 1 * REAGENTS_METABOLISM - color = "#AB7878" // rgb: 171, 120, 120 - - on_mob_life(var/mob/living/M as mob) - M.nutrition += nutriment_factor - if(istype(M, /mob/living/carbon/human) && M.mind) - if(M.mind.special_role) - if(!M) M = holder.my_atom - M.heal_organ_damage(1,1) - M.nutrition += nutriment_factor - ..() - return - ..() -*/ cornoil name = "Corn Oil" id = "cornoil" @@ -2729,7 +2544,7 @@ datum ..() return -/* We're back to flour bags + flour name = "flour" id = "flour" @@ -2747,7 +2562,6 @@ datum src = null if(!istype(T, /turf/space)) new /obj/effect/decal/cleanable/flour(T) -*/ rice name = "Rice" @@ -3297,7 +3111,7 @@ datum on_mob_life(var/mob/living/M as mob, var/alien) // Sobering multiplier. // Sober block makes it more difficult to get drunk - var/sober_str=!(M_SOBER in M.mutations)?1:2 + var/sober_str=!(SOBER in M.mutations)?1:2 M:nutrition += nutriment_factor holder.remove_reagent(src.id, FOOD_METABOLISM) if(!src.data) data = 1 @@ -3351,6 +3165,13 @@ datum usr << "It wasn't enough..." return + reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume)//Splashing people with ethanol isn't quite as good as fuel. + if(!istype(M, /mob/living)) + return + if(method == TOUCH) + M.adjust_fire_stacks(volume / 15) + return + beer //It's really much more stronger than other drinks. name = "Beer" id = "beer" @@ -3630,6 +3451,11 @@ datum reagent_state = LIQUID color = "#664300" // rgb: 102, 67, 0 + on_mob_life(var/mob/living/M as mob) + M.Stun(2) + ..() + return + changelingsting name = "Changeling Sting" id = "changelingsting" @@ -3867,10 +3693,6 @@ datum reagent_state = LIQUID color = "#664300" // rgb: 102, 67, 0 - on_mob_life(var/mob/living/M as mob) - ..() - M.stunned = 4 - return neurotoxin name = "Neurotoxin" @@ -3880,12 +3702,22 @@ datum color = "#2E2E61" // rgb: 46, 46, 97 on_mob_life(var/mob/living/M as mob) + M.weakened = max(M.weakened, 3) + if(!data) + data = 1 + data++ + M.dizziness +=6 + if(data >= 15 && data <45) + if (!M.slurring) + M.slurring = 1 + M.slurring += 3 + else if(data >= 45 && prob(50) && data <55) + M.confused = max(M.confused+3,0) + else if(data >=55) + M.druggy = max(M.druggy, 55) + else if(data >=200) + M.adjustToxLoss(2) ..() - if(!M) M = holder.my_atom - M:adjustOxyLoss(0.5) - M:adjustOxyLoss(0.5) - M:weakened = max(M:weakened, 15) - M:silent = max(M:silent, 15) return bananahonk @@ -3987,28 +3819,11 @@ datum return - -//Fox -/////////////////Requires Further Balance Testing////////////////// -/* - lectrazine - name = "Lectrazine" - id = "lectrazine" - description = "An extremly powerful cardiostimulant and analgesic which is used in revival of deceased." - reagent_state = LIQUID - color = "#080000" - custom_metabolism = 0.1 - - reaction_mob(var/mob/living/carbon/M as mob, var/methode=INGEST) - if(!M) M = holder.my_atom - M.stat = CONSCIOUS - M.setOxyLoss(0) - M.heal_organ_damage(15,0) - M.SetParalysis(15) - M.adjustBrainLoss(10*REM) - return - - -*/ // Undefine the alias for REAGENTS_EFFECT_MULTIPLER -#undef REM \ No newline at end of file +#undef REM + + +/datum/reagent/Destroy() + if(holder) + holder.reagent_list -= src + holder = null diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index e768546c883..98806674a51 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -31,12 +31,6 @@ datum on_reaction(var/datum/reagents/holder, var/created_volume) var/datum/effect/effect/system/reagents_explosion/e = new() e.set_up(round (created_volume/10, 1), holder.my_atom, 0, 0) - e.holder_damage(holder.my_atom) - if(isliving(holder.my_atom)) - e.amount *= 0.5 - var/mob/living/L = holder.my_atom - if(L.stat!=DEAD) - e.amount *= 0.5 e.start() holder.clear_reagents() return @@ -333,19 +327,12 @@ datum required_reagents = list("oxygen" = 1, "anti_toxin" = 1, "carbon" = 1) result_amount = 3 - ethanoloxidation - name = "ethanoloxidation" //Kind of a placeholder in case someone ever changes it so that chemicals - id = "ethanoloxidation" // react in the body. Also it would be silly if it didn't exist. - result = "water" - required_reagents = list("ethylredoxrazine" = 1, "ethanol" = 1) - result_amount = 2 - glycerol name = "Glycerol" id = "glycerol" result = "glycerol" - required_reagents = list("cornoil" = 3, "sacid" = 2) - result_amount = 5 + required_reagents = list("cornoil" = 3, "sacid" = 1) + result_amount = 1 nitroglycerin name = "Nitroglycerin" @@ -356,12 +343,6 @@ datum on_reaction(var/datum/reagents/holder, var/created_volume) var/datum/effect/effect/system/reagents_explosion/e = new() e.set_up(round (created_volume/2, 1), holder.my_atom, 0, 0) - e.holder_damage(holder.my_atom) - if(isliving(holder.my_atom)) - e.amount *= 0.5 - var/mob/living/L = holder.my_atom - if(L.stat!=DEAD) - e.amount *= 0.5 e.start() holder.clear_reagents() @@ -385,23 +366,14 @@ datum var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(2, 1, location) s.start() - for(var/mob/living/carbon/M in viewers(world.view, location)) - switch(get_dist(M, location)) - if(0 to 3) - if(hasvar(M, "glasses")) - if(istype(M:glasses, /obj/item/clothing/glasses/sunglasses)) - continue - - flick("e_flash", M.flash) - M.Weaken(15) - - if(4 to 5) - if(hasvar(M, "glasses")) - if(istype(M:glasses, /obj/item/clothing/glasses/sunglasses)) - continue - - flick("e_flash", M.flash) - M.Stun(5) + for(var/mob/living/carbon/C in hearers(5, location)) + if(C.eyecheck()) + continue + flick("e_flash", C.flash) + if(get_dist(C, location) < 4) + C.Weaken(5) + continue + C.Stun(5) napalm name = "Napalm" @@ -426,33 +398,6 @@ datum holder.del_reagent("napalm") return - /* - smoke - name = "Smoke" - id = "smoke" - result = null - required_reagents = list("potassium" = 1, "sugar" = 1, "phosphorus" = 1 ) - result_amount = null - secondary = 1 - on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - var/datum/effect/system/bad_smoke_spread/S = new /datum/effect/system/bad_smoke_spread - S.attach(location) - S.set_up(10, 0, location) - playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3) - spawn(0) - S.start() - sleep(10) - S.start() - sleep(10) - S.start() - sleep(10) - S.start() - sleep(10) - S.start() - holder.clear_reagents() - return */ - chemsmoke name = "Chemsmoke" id = "chemsmoke" @@ -480,20 +425,6 @@ datum required_reagents = list("ethanol" = 1, "chlorine" = 3, "water" = 1) result_amount = 1 - potassium_chloride - name = "Potassium Chloride" - id = "potassium_chloride" - result = "potassium_chloride" - required_reagents = list("sodiumchloride" = 1, "potassium" = 1) - result_amount = 2 - - potassium_chlorophoride - name = "Potassium Chlorophoride" - id = "potassium_chlorophoride" - result = "potassium_chlorophoride" - required_reagents = list("potassium_chloride" = 1, "plasma" = 1, "chloralhydrate" = 1) - result_amount = 4 - stoxin name = "Sleep Toxin" id = "stoxin" @@ -505,8 +436,8 @@ datum name = "Zombie Powder" id = "zombiepowder" result = "zombiepowder" - required_reagents = list("carpotoxin" = 1, "stoxin" = 1, "copper" = 1) - result_amount = 3 + required_reagents = list("carpotoxin" = 5, "stoxin" = 5, "copper" = 5) + result_amount = 2 mutetoxin name = "Mute toxin" @@ -730,290 +661,32 @@ datum required_reagents = list("chlorine" = 1, "hydrogen" = 1, "nitrogen" = 1) result_amount = 3 - -/////////////////////////////////////OLD SLIME CORE REACTIONS /////////////////////////////// -/* - slimepepper - name = "Slime Condensedcapaicin" - id = "m_condensedcapaicin" - result = "condensedcapsaicin" - required_reagents = list("sugar" = 1) - result_amount = 1 - required_container = /obj/item/slime_core - required_other = 1 - slimefrost - name = "Slime Frost Oil" - id = "m_frostoil" - result = "frostoil" - required_reagents = list("water" = 1) - result_amount = 1 - required_container = /obj/item/slime_core - required_other = 1 - slimeglycerol - name = "Slime Glycerol" - id = "m_glycerol" - result = "glycerol" - required_reagents = list("blood" = 1) - result_amount = 1 - required_container = /obj/item/slime_core - required_other = 1 - - slime_explosion - name = "Slime Explosion" - id = "m_explosion" - result = null - required_reagents = list("blood" = 1) - result_amount = 2 - required_container = /obj/item/slime_core - required_other = 2 +///////Changeling Blood Test///////////// + changeling_test + name = "Changeling blood test" + id = "changelingblood" + result = "blood" + required_reagents = list("blood" = 5) + required_catalysts = list("fuel") + result_amount = 1 //Needs this in order to check the donor, as the data var in the reacted blood gets transferred. on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - var/datum/effect/effect/system/reagents_explosion/e = new() - e.set_up(round (created_volume/10, 1), location, 0, 0) - e.start() - - holder.clear_reagents() - return - slimejam - name = "Slime Jam" - id = "m_jam" - result = "slimejelly" - required_reagents = list("water" = 1) - result_amount = 1 - required_container = /obj/item/slime_core - required_other = 2 - slimesynthi - name = "Slime Synthetic Flesh" - id = "m_flesh" - result = null - required_reagents = list("sugar" = 1) - result_amount = 1 - required_container = /obj/item/slime_core - required_other = 2 - on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - new /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh(location) + if(!holder.reagent_list) //reagent_list is not null + return + var/datum/reagent/blood/B = locate() in holder.reagent_list + if(!B) //B is not null + return + var/mob/living/carbon/human/H = B.data["donor"] + if(!H) //H is not null. + return + if(H.mind && H.mind.changeling) //Checks if H, the blood donor is a ling. + for(var/mob/M in viewers(get_turf_loc(holder.my_atom), null)) + M.show_message( "The blood writhes and wriggles and sizzles away from the container!", 1, "You hear bubbling and sizzling.", 2) + else + for(var/mob/M in viewers(get_turf_loc(holder.my_atom), null)) + M.show_message( "The blood seems to break apart in the fuel.", 1) + holder.del_reagent("blood") return - slimeenzyme - name = "Slime Enzyme" - id = "m_enzyme" - result = "enzyme" - required_reagents = list("blood" = 1, "water" = 1) - result_amount = 2 - required_container = /obj/item/slime_core - required_other = 3 - slimeplasma - name = "Slime Plasma" - id = "m_plasma" - result = "plasma" - required_reagents = list("sugar" = 1, "blood" = 2) - result_amount = 2 - required_container = /obj/item/slime_core - required_other = 3 - slimevirus - name = "Slime Virus" - id = "m_virus" - result = null - required_reagents = list("sugar" = 1, "sacid" = 1) - result_amount = 2 - required_container = /obj/item/slime_core - required_other = 3 - on_reaction(var/datum/reagents/holder, var/created_volume) - holder.clear_reagents() - - var/virus = pick(/datum/disease/advance/flu, /datum/disease/advance/cold, \ - /datum/disease/pierrot_throat, /datum/disease/fake_gbs, \ - /datum/disease/brainrot, /datum/disease/magnitis) - - - var/datum/disease/F = new virus(0) - var/list/data = list("viruses"= list(F)) - holder.add_reagent("blood", 20, data) - - holder.add_reagent("cyanide", rand(1,10)) - - return - - slimeteleport - name = "Slime Teleport" - id = "m_tele" - result = null - required_reagents = list("pacid" = 2, "mutagen" = 2) - required_catalysts = list("plasma" = 1) - result_amount = 1 - required_container = /obj/item/slime_core - required_other = 4 - on_reaction(var/datum/reagents/holder, var/created_volume) - - // Calculate new position (searches through beacons in world) - var/obj/item/device/radio/beacon/chosen - var/list/possible = list() - for(var/obj/item/device/radio/beacon/W in world) - possible += W - - if(possible.len > 0) - chosen = pick(possible) - - if(chosen) - // Calculate previous position for transition - - var/turf/FROM = get_turf_loc(holder.my_atom) // the turf of origin we're travelling FROM - var/turf/TO = get_turf_loc(chosen) // the turf of origin we're travelling TO - - playsound(TO, 'sound/effects/phasein.ogg', 100, 1) - - var/list/flashers = list() - for(var/mob/living/carbon/human/M in viewers(TO, null)) - if(M:eyecheck() <= 0) - flick("e_flash", M.flash) // flash dose faggots - flashers += M - - var/y_distance = TO.y - FROM.y - var/x_distance = TO.x - FROM.x - for (var/atom/movable/A in range(2, FROM )) // iterate thru list of mobs in the area - if(istype(A, /obj/item/device/radio/beacon)) continue // don't teleport beacons because that's just insanely stupid - if( A.anchored && !istype(A, /mob/dead/observer) ) continue // don't teleport anchored things (computers, tables, windows, grilles, etc) because this causes problems! - // do teleport ghosts however because hell why not - - var/turf/newloc = locate(A.x + x_distance, A.y + y_distance, TO.z) // calculate the new place - if(!A.Move(newloc)) // if the atom, for some reason, can't move, FORCE them to move! :) We try Move() first to invoke any movement-related checks the atom needs to perform after moving - A.loc = locate(A.x + x_distance, A.y + y_distance, TO.z) - - spawn() - if(ismob(A) && !(A in flashers)) // don't flash if we're already doing an effect - var/mob/M = A - if(M.client) - var/obj/blueeffect = new /obj(src) - blueeffect.screen_loc = "WEST,SOUTH to EAST,NORTH" - blueeffect.icon = 'icons/effects/effects.dmi' - blueeffect.icon_state = "shieldsparkles" - blueeffect.layer = 17 - blueeffect.mouse_opacity = 0 - M.client.screen += blueeffect - sleep(20) - M.client.screen -= blueeffect - del(blueeffect) - slimecrit - name = "Slime Crit" - id = "m_tele" - result = null - required_reagents = list("sacid" = 1, "blood" = 1) - required_catalysts = list("plasma" = 1) - result_amount = 1 - required_container = /obj/item/slime_core - required_other = 4 - on_reaction(var/datum/reagents/holder, var/created_volume) - - var/blocked = list(/mob/living/simple_animal/hostile, - /mob/living/simple_animal/hostile/pirate, - /mob/living/simple_animal/hostile/pirate/ranged, - /mob/living/simple_animal/hostile/russian, - /mob/living/simple_animal/hostile/russian/ranged, - /mob/living/simple_animal/hostile/syndicate, - /mob/living/simple_animal/hostile/syndicate/melee, - /mob/living/simple_animal/hostile/syndicate/melee/space, - /mob/living/simple_animal/hostile/syndicate/ranged, - /mob/living/simple_animal/hostile/syndicate/ranged/space, - /mob/living/simple_animal/hostile/alien/queen/large, - /mob/living/simple_animal/clown - )//exclusion list for things you don't want the reaction to create. - var/list/critters = typesof(/mob/living/simple_animal/hostile) - blocked // list of possible hostile mobs - - playsound(get_turf_loc(holder.my_atom), 'sound/effects/phasein.ogg', 100, 1) - - for(var/mob/living/carbon/human/M in viewers(get_turf_loc(holder.my_atom), null)) - if(M:eyecheck() <= 0) - flick("e_flash", M.flash) - - for(var/i = 1, i <= created_volume, i++) - var/chosen = pick(critters) - var/mob/living/simple_animal/hostile/C = new chosen - C.loc = get_turf_loc(holder.my_atom) - if(prob(50)) - for(var/j = 1, j <= rand(1, 3), j++) - step(C, pick(NORTH,SOUTH,EAST,WEST)) - slimebork - name = "Slime Bork" - id = "m_tele" - result = null - required_reagents = list("sugar" = 1, "water" = 1) - result_amount = 2 - required_container = /obj/item/slime_core - required_other = 4 - on_reaction(var/datum/reagents/holder, var/created_volume) - - var/list/borks = typesof(/obj/item/weapon/reagent_containers/food/snacks) - /obj/item/weapon/reagent_containers/food/snacks - // BORK BORK BORK - - playsound(get_turf_loc(holder.my_atom), 'sound/effects/phasein.ogg', 100, 1) - - for(var/mob/living/carbon/human/M in viewers(get_turf_loc(holder.my_atom), null)) - if(M:eyecheck() <= 0) - flick("e_flash", M.flash) - - for(var/i = 1, i <= created_volume + rand(1,2), i++) - var/chosen = pick(borks) - var/obj/B = new chosen - if(B) - B.loc = get_turf_loc(holder.my_atom) - if(prob(50)) - for(var/j = 1, j <= rand(1, 3), j++) - step(B, pick(NORTH,SOUTH,EAST,WEST)) - - - - slimechloral - name = "Slime Chloral" - id = "m_bunch" - result = "chloralhydrate" - required_reagents = list("blood" = 1, "water" = 2) - result_amount = 2 - required_container = /obj/item/slime_core - required_other = 5 - slimeretro - name = "Slime Retro" - id = "m_xeno" - result = null - required_reagents = list("sugar" = 1) - result_amount = 1 - required_container = /obj/item/slime_core - required_other = 5 - on_reaction(var/datum/reagents/holder, var/created_volume) - var/datum/disease/F = new /datum/disease/dna_retrovirus(0) - var/list/data = list("viruses"= list(F)) - holder.add_reagent("blood", 20, data) - slimefoam - name = "Slime Foam" - id = "m_foam" - result = null - required_reagents = list("sacid" = 1) - result_amount = 2 - required_container = /obj/item/slime_core - required_other = 5 - - on_reaction(var/datum/reagents/holder, var/created_volume) - - - var/location = get_turf(holder.my_atom) - for(var/mob/M in viewers(5, location)) - M << "\red The solution violently bubbles!" - - location = get_turf(holder.my_atom) - - for(var/mob/M in viewers(5, location)) - M << "\red The solution spews out foam!" - - //world << "Holder volume is [holder.total_volume]" - //for(var/datum/reagent/R in holder.reagent_list) - // world << "[R.name] = [R.volume]" - - var/datum/effect/effect/system/foam_spread/s = new() - s.set_up(created_volume, location, holder, 0) - s.start() - holder.clear_reagents() - return -*/ /////////////////////////////////////////////NEW SLIME CORE REACTIONS///////////////////////////////////////////// //Grey @@ -1323,7 +996,7 @@ datum required_container = /obj/item/slime_extract/yellow required_other = 1 on_reaction(var/datum/reagents/holder, var/created_volume) - var/obj/item/weapon/cell/slime/P = new /obj/item/weapon/cell/slime + var/obj/item/weapon/stock_parts/cell/slime/P = new /obj/item/weapon/stock_parts/cell/slime P.loc = get_turf_loc(holder.my_atom) slimeglow @@ -1466,7 +1139,7 @@ datum required_other = 1 on_reaction(var/datum/reagents/holder) feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") - var/obj/effect/golem_rune/Z = new /obj/effect/golem_rune + var/obj/effect/goleRUNe/Z = new /obj/effect/goleRUNe Z.loc = get_turf(holder.my_atom) Z.announce_to_ghosts() //Bluespace @@ -2195,20 +1868,4 @@ datum id = "rewriter" result = "rewriter" required_reagents = list("spacemountainwind" = 1, "coffee" = 1) - result_amount = 2 - - - -//Fox -///////////////////////Requires Balance Testing/////////////////// -/* - lectrazine - name = "Lectrazine" - id = "lectrazine" - result = "lectrazine" - required_reagents = list("inaprovaline" = 1, "phosphorus" = 1) - required_catalysts = list("silver" = 5) - result_amount = 2 - -*/ - + result_amount = 2 \ No newline at end of file diff --git a/code/modules/reagents/dartgun.dm b/code/modules/reagents/dartgun.dm index 1381fa5b6d7..151b6ea1841 100644 --- a/code/modules/reagents/dartgun.dm +++ b/code/modules/reagents/dartgun.dm @@ -70,7 +70,7 @@ for(var/datum/reagent/R in B.reagents.reagent_list) usr << "\blue [R.volume] units of [R.name]" -/obj/item/weapon/gun/dartgun/attackby(obj/item/I as obj, mob/user as mob) +/obj/item/weapon/gun/dartgun/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/weapon/dart_cartridge)) var/obj/item/weapon/dart_cartridge/D = I @@ -297,4 +297,17 @@ starting_chems = list("kelotane","bicaridine","anti_toxin") /obj/item/weapon/gun/dartgun/vox/raider - starting_chems = list("space_drugs","stoxin","impedrezene") \ No newline at end of file + starting_chems = list("space_drugs","stoxin","impedrezene") + +/obj/effect/syringe_gun_dummy //moved this shitty thing here + name = "" + desc = "" + icon = 'icons/obj/chemical.dmi' + icon_state = "null" + anchored = 1 + density = 0 + + New() + var/datum/reagents/R = new/datum/reagents(15) + reagents = R + R.my_atom = src \ No newline at end of file diff --git a/code/modules/reagents/grenade_launcher.dm b/code/modules/reagents/grenade_launcher.dm index 43fe7311938..54538e57a7b 100644 --- a/code/modules/reagents/grenade_launcher.dm +++ b/code/modules/reagents/grenade_launcher.dm @@ -20,7 +20,7 @@ usr << "\icon [src] Grenade launcher:" usr << "\blue [grenades] / [max_grenades] Grenades." - attackby(obj/item/I as obj, mob/user as mob) + attackby(obj/item/I as obj, mob/user as mob, params) if((istype(I, /obj/item/weapon/grenade))) if(grenades.len < max_grenades) diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 911ce73784c..76c4b2bcb6f 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -39,7 +39,7 @@ // possibly intentional, but removing it allows us to not duplicate functionality. // -Sayu (storage conslidation) /* -/obj/item/weapon/reagent_containers/attackby(obj/item/I as obj, mob/user as mob) +/obj/item/weapon/reagent_containers/attackby(obj/item/I as obj, mob/user as mob, params) return */ /obj/item/weapon/reagent_containers/afterattack(obj/target, mob/user , flag) diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm index 31d68ef7b15..afe56a4f731 100644 --- a/code/modules/reagents/reagent_containers/borghydro.dm +++ b/code/modules/reagents/reagent_containers/borghydro.dm @@ -8,7 +8,6 @@ amount_per_transfer_from_this = 5 volume = 30 possible_transfer_amounts = null - flags = FPRINT var/mode = 1 var/charge_cost = 50 var/charge_tick = 0 @@ -68,14 +67,14 @@ var/datum/reagents/R = reagent_list[reagent_list.len] R.add_reagent(reagent, 30) -/obj/item/weapon/reagent_containers/borghypo/attack(mob/M as mob, mob/user as mob) +/obj/item/weapon/reagent_containers/borghypo/attack(mob/living/M as mob, mob/user as mob) var/datum/reagents/R = reagent_list[mode] if(!R.total_volume) user << "\red The injector is empty." return - if (!( istype(M, /mob) )) + if (!(istype(M))) return - if (R.total_volume) + if (R.total_volume && M.can_inject(user,1)) user << "\blue You inject [M] with the injector." M << "\red You feel a tiny prick!" diff --git a/code/modules/reagents/reagent_containers/drugs.dm b/code/modules/reagents/reagent_containers/drugs.dm index 1f9dced0500..bbe868e5430 100644 --- a/code/modules/reagents/reagent_containers/drugs.dm +++ b/code/modules/reagents/reagent_containers/drugs.dm @@ -8,7 +8,7 @@ amount_per_transfer_from_this = 2 possible_transfer_amounts = 2 volume = 10 - flags = FPRINT | TABLEPASS | OPENCONTAINER + flags = OPENCONTAINER var/label_text = "" @@ -91,7 +91,7 @@ return - attackby(obj/item/weapon/W as obj, mob/user as mob) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/pen) || istype(W, /obj/item/device/flashlight/pen)) var/tmp_label = sanitize(input(user, "Enter a label for [src.name]","Label",src.label_text)) if(length(tmp_label) > 10) diff --git a/code/modules/reagents/reagent_containers/food/condiment.dm b/code/modules/reagents/reagent_containers/food/condiment.dm index bd61291a099..5b7383f04d6 100644 --- a/code/modules/reagents/reagent_containers/food/condiment.dm +++ b/code/modules/reagents/reagent_containers/food/condiment.dm @@ -10,14 +10,14 @@ desc = "Just your average condiment container." icon = 'icons/obj/food.dmi' icon_state = "emptycondiment" - flags = FPRINT | TABLEPASS | OPENCONTAINER + flags = OPENCONTAINER possible_transfer_amounts = list(1,5,10) volume = 50 //Possible_states has the reagent id as key and a list of, in order, the icon_state, the name and the desc as values. Used in the on_reagent_change() to change names, descs and sprites. var/list/possible_states = list("ketchup" = list("ketchup", "Ketchup", "You feel more American already."), "capsaicin" = list("hotsauce", "Hotsauce", "You can almost TASTE the stomach ulcers now!"), "enzyme" = list("enzyme", "Universal Enzyme", "Used in cooking various dishes"), "soysauce" = list("soysauce", "Soy Sauce", "A salty soy-based flavoring"), "frostoil" = list("coldsauce", "Coldsauce", "Leaves the tongue numb in it's passage"), "sodiumchloride" = list("saltshaker", "Salt Shaker", "Salt. From space oceans, presumably"), "blackpepper" = list("pepermillsmall", "Pepper Mill", "Often used to flavor food or make people sneeze"), "cornoil" = list("oliveoil", "Corn Oil", "A delicious oil used in cooking. Made from corn"), "sugar" = list("emptycondiment", "Sugar", "Tasty spacey sugar!")) -/obj/item/weapon/reagent_containers/food/condiment/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/reagent_containers/food/condiment/attackby(obj/item/weapon/W as obj, mob/user as mob, params) return @@ -66,7 +66,7 @@ return 1 return 0 -/obj/item/weapon/reagent_containers/food/condiment/attackby(obj/item/I as obj, mob/user as mob) +/obj/item/weapon/reagent_containers/food/condiment/attackby(obj/item/I as obj, mob/user as mob, params) return /obj/item/weapon/reagent_containers/food/condiment/afterattack(obj/target, mob/user , proximity) @@ -172,7 +172,6 @@ volume = 10 amount_per_transfer_from_this = 10 possible_transfer_amounts = 10 - flags = FPRINT | TABLEPASS possible_states = list("ketchup" = list("condi_ketchup", "Ketchup", "You feel more American already."), "capsaicin" = list("condi_hotsauce", "Hotsauce", "You can almost TASTE the stomach ulcers now!"), "soysauce" = list("condi_soysauce", "Soy Sauce", "A salty soy-based flavoring"), "frostoil" = list("condi_frostoil", "Coldsauce", "Leaves the tongue numb in it's passage"), "sodiumchloride" = list("condi_salt", "Salt Shaker", "Salt. From space oceans, presumably"), "blackpepper" = list("condi_pepper", "Pepper Mill", "Often used to flavor food or make people sneeze"), "cornoil" = list("condi_cornoil", "Corn Oil", "A delicious oil used in cooking. Made from corn"), "sugar" = list("condi_sugar", "Sugar", "Tasty spacey sugar!")) var/originalname = "condiment" //Can't use initial(name) for this. This stores the name set by condimasters. diff --git a/code/modules/reagents/reagent_containers/food/drinks.dm b/code/modules/reagents/reagent_containers/food/drinks.dm index 25a4fd2f47a..2024b18c95f 100644 --- a/code/modules/reagents/reagent_containers/food/drinks.dm +++ b/code/modules/reagents/reagent_containers/food/drinks.dm @@ -6,7 +6,7 @@ desc = "yummy" icon = 'icons/obj/drinks.dmi' icon_state = null - flags = FPRINT | TABLEPASS | OPENCONTAINER + flags = OPENCONTAINER var/gulp_size = 5 //This is now officially broken ... need to think of a nice way to fix it. possible_transfer_amounts = list(5,10,25) volume = 50 @@ -161,7 +161,7 @@ amount_per_transfer_from_this = 20 possible_transfer_amounts = null volume = 150 - flags = FPRINT | CONDUCT | TABLEPASS | OPENCONTAINER + flags = CONDUCT | OPENCONTAINER /obj/item/weapon/reagent_containers/food/drinks/golden_cup/tournament_26_06_2011 desc = "A golden cup. It will be presented to a winner of tournament 26 june and name of the winner will be graved on it." diff --git a/code/modules/reagents/reagent_containers/food/sandwich.dm b/code/modules/reagents/reagent_containers/food/sandwich.dm index 585a1c3711a..1ecb6bdf897 100644 --- a/code/modules/reagents/reagent_containers/food/sandwich.dm +++ b/code/modules/reagents/reagent_containers/food/sandwich.dm @@ -1,10 +1,10 @@ /* -/obj/item/weapon/reagent_containers/food/snacks/breadslice/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/weapon/reagent_containers/food/snacks/breadslice/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/shard) || istype(W,/obj/item/weapon/reagent_containers/food/snacks)) var/obj/item/weapon/reagent_containers/food/snacks/csandwich/S = new(get_turf(src)) - S.attackby(W,user) + S.attackby(W,user, params) del(src) ..() @@ -17,7 +17,7 @@ var/list/ingredients = list() -/obj/item/weapon/reagent_containers/food/snacks/csandwich/attackby(obj/item/W as obj, mob/user as mob) +/obj/item/weapon/reagent_containers/food/snacks/csandwich/attackby(obj/item/W as obj, mob/user as mob, params) var/sandwich_limit = 4 for(var/obj/item/O in ingredients) diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm index fb025cb37da..18e9ee854db 100644 --- a/code/modules/reagents/reagent_containers/food/snacks.dm +++ b/code/modules/reagents/reagent_containers/food/snacks.dm @@ -22,7 +22,7 @@ if(M == usr) usr << "You finish eating \the [src]." usr.visible_message("[usr] finishes eating \the [src].") - usr.drop_from_inventory(src) //so icons update :[ + usr.unEquip(src) //so icons update :[ if(trash) if(ispath(trash,/obj/item)) @@ -39,7 +39,7 @@ /obj/item/weapon/reagent_containers/food/snacks/attack(mob/M as mob, mob/user as mob, def_zone) if(!reagents.total_volume) //Shouldn't be needed but it checks to see if it has anything left in it. user << "\red None of [src] left, oh no!" - M.drop_from_inventory(src) //so icons update :[ + M.unEquip(src) //so icons update :[ del(src) return 0 @@ -134,14 +134,14 @@ usr << "\blue \The [src] was bitten multiple times!" -/obj/item/weapon/reagent_containers/food/snacks/attackby(obj/item/weapon/W, mob/user) +/obj/item/weapon/reagent_containers/food/snacks/attackby(obj/item/weapon/W, mob/user, params) if(istype(W,/obj/item/weapon/pen)) - var/n_name = copytext(sanitize(input(usr, "What would you like to name this dish?", "Food Renaming", null) as text), 1, MAX_NAME_LEN) + var/n_name = sanitize(copytext(input(usr, "What would you like to name this dish?", "Food Renaming", null) as text, 1, MAX_NAME_LEN)) if((loc == usr && usr.stat == 0)) name = "[n_name]" return if(istype(W,/obj/item/weapon/storage)) - ..() // -> item/attackby() + ..() // -> item/attackby(, params) if(istype(W,/obj/item/weapon/kitchen/utensil)) @@ -194,7 +194,7 @@ if(!iscarbon(user)) return 1 user << "\red You slip [W] inside [src]." - user.u_equip(W) + user.unEquip(W) if ((user.client && user.s_active != src)) user.client.screen -= W W.dropped(user) @@ -207,7 +207,7 @@ !isturf(src.loc) || \ !(locate(/obj/structure/table) in src.loc) && \ !(locate(/obj/machinery/optable) in src.loc) && \ - !(locate(/obj/item/weapon/tray) in src.loc) \ + !(locate(/obj/item/weapon/storage/bag/tray) in src.loc) \ ) user << "\red You cannot slice [src] here! You need a table or at least a tray to do it." return 1 @@ -237,18 +237,23 @@ something.loc = get_turf(src) ..() -/obj/item/weapon/reagent_containers/food/snacks/attack_animal(var/mob/M) +/obj/item/weapon/reagent_containers/food/snacks/attack_animal(mob/M) if(isanimal(M)) if(iscorgi(M)) - if(bitecount == 0 || prob(50)) - M.emote("nibbles away at the [src]") - bitecount++ - if(bitecount >= 5) - var/sattisfaction_text = pick("burps from enjoyment", "yaps for more", "woofs twice", "looks at the area where the [src] was") - if(sattisfaction_text) - M.emote("[sattisfaction_text]") + if(bitecount >= 4) + M.visible_message("[M] [pick("burps from enjoyment", "yaps for more", "woofs twice", "looks at the area where \the [src] was")].","You swallow up the last part of \the [src].") + playsound(src.loc,'sound/items/eatfood.ogg', rand(10,50), 1) + var/mob/living/simple_animal/corgi/C = M + if (C.health <= C.maxHealth + 5) + C.health += 5 + else + C.health = C.maxHealth del(src) - if(ismouse(M)) + else + M.visible_message("[M] takes a bite of \the [src].","You take a bite of \the [src].") + playsound(src.loc,'sound/items/eatfood.ogg', rand(10,50), 1) + bitecount++ + else if(ismouse(M)) var/mob/living/simple_animal/mouse/N = M N << text("\blue You nibble away at [src].") if(prob(50)) @@ -525,7 +530,7 @@ src.visible_message("\red [src.name] has been squashed.","\red You hear a smack.") del(src) - attackby(obj/item/weapon/W as obj, mob/user as mob) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype( W, /obj/item/toy/crayon )) var/obj/item/toy/crayon/C = W var/clr = C.colourName @@ -1243,8 +1248,7 @@ icon_state = "chinese2" New() ..() - reagents.add_reagent("nutriment", 5) - reagents.add_reagent("carpotoxin", 1) + reagents.add_reagent("nutriment", 6) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/chinese/newdles @@ -2230,7 +2234,7 @@ ..() reagents.add_reagent("nutriment", 3) bitesize = 1 - attackby(obj/item/weapon/W as obj, mob/user as mob) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/kitchen/rollingpin)) user.visible_message( \ "[user] flattens the dough with the rolling pin!", \ @@ -2850,7 +2854,7 @@ update_icon() -/obj/item/pizzabox/attackby( obj/item/I as obj, mob/user as mob ) +/obj/item/pizzabox/attackby( obj/item/I as obj, mob/user as mob , params) if( istype(I, /obj/item/pizzabox/) ) var/obj/item/pizzabox/box = I @@ -3152,7 +3156,7 @@ reagents.add_reagent("nutriment", 3) // Flour + egg = dough -/obj/item/weapon/reagent_containers/food/snacks/flour/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/reagent_containers/food/snacks/flour/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/reagent_containers/food/snacks/egg)) new /obj/item/weapon/reagent_containers/food/snacks/dough(src) user << "You make some dough." @@ -3160,7 +3164,7 @@ del(src) // Egg + flour = dough -/obj/item/weapon/reagent_containers/food/snacks/egg/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/reagent_containers/food/snacks/egg/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/reagent_containers/food/snacks/flour)) new /obj/item/weapon/reagent_containers/food/snacks/dough(src) user << "You make some dough." @@ -3178,7 +3182,7 @@ reagents.add_reagent("nutriment", 3) // Dough + rolling pin = flat dough -/obj/item/weapon/reagent_containers/food/snacks/dough/attackby(obj/item/I, mob/user) +/obj/item/weapon/reagent_containers/food/snacks/dough/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/weapon/kitchen/rollingpin)) if(isturf(loc)) new /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough(loc) @@ -3281,7 +3285,7 @@ reagents.add_reagent("nutriment", 3) // potato + knife = raw sticks -/obj/item/weapon/reagent_containers/food/snacks/grown/potato/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/reagent_containers/food/snacks/grown/potato/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/kitchen/utensil/knife)) new /obj/item/weapon/reagent_containers/food/snacks/rawsticks(src) user << "You cut the potato." diff --git a/code/modules/reagents/reagent_containers/food/snacks/grown.dm b/code/modules/reagents/reagent_containers/food/snacks/grown.dm index c3d41be9820..d3acf96a7fb 100644 --- a/code/modules/reagents/reagent_containers/food/snacks/grown.dm +++ b/code/modules/reagents/reagent_containers/food/snacks/grown.dm @@ -82,14 +82,14 @@ filling_color = "#E6E8DA" plantname = "potato" -/obj/item/weapon/reagent_containers/food/snacks/grown/potato/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/reagent_containers/food/snacks/grown/potato/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if(istype(W, /obj/item/stack/cable_coil)) if(W:amount >= 5) W:amount -= 5 if(!W:amount) del(W) user << "You add some cable to the potato and slide it inside the battery encasing." - var/obj/item/weapon/cell/potato/pocell = new /obj/item/weapon/cell/potato(user.loc) + var/obj/item/weapon/stock_parts/cell/potato/pocell = new /obj/item/weapon/stock_parts/cell/potato(user.loc) pocell.maxcharge = src.potency * 10 pocell.charge = pocell.maxcharge del(src) @@ -239,9 +239,9 @@ filling_color = "#125709" plantname = "ambrosia" -/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris/attackby(var/obj/item/W as obj, var/mob/user as mob) +/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris/attackby(var/obj/item/W as obj, var/mob/user as mob, params) if(istype(W, /obj/item/weapon/rollingpaper)) - user.u_equip(W) + user.unEquip(W) var/obj/item/clothing/mask/cigarette/joint/J = new /obj/item/clothing/mask/cigarette/joint(user.loc) J.chem_volume = src.reagents.total_volume src.reagents.trans_to(J, J.chem_volume) @@ -262,9 +262,9 @@ filling_color = "#229E11" plantname = "ambrosiadeus" -/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus/attackby(var/obj/item/W as obj, var/mob/user as mob) +/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus/attackby(var/obj/item/W as obj, var/mob/user as mob, params) if(istype(W, /obj/item/weapon/rollingpaper)) - user.u_equip(W) + user.unEquip(W) var/obj/item/clothing/mask/cigarette/joint/deus/J = new /obj/item/clothing/mask/cigarette/joint/deus(user.loc) J.chem_volume = src.reagents.total_volume src.reagents.trans_to(J, J.chem_volume) @@ -317,7 +317,7 @@ filling_color = "#FAB728" plantname = "pumpkin" -/obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if(istype(W, /obj/item/weapon/circular_saw) || istype(W, /obj/item/weapon/hatchet) || istype(W, /obj/item/weapon/twohanded/fireaxe) || istype(W, /obj/item/weapon/kitchen/utensil/knife) || istype(W, /obj/item/weapon/kitchenknife) || istype(W, /obj/item/weapon/melee/energy)) user.show_message("You carve a face into [src]!", 1) diff --git a/code/modules/reagents/reagent_containers/food/snacks/meat.dm b/code/modules/reagents/reagent_containers/food/snacks/meat.dm index d0c0e707c36..630035ef87d 100644 --- a/code/modules/reagents/reagent_containers/food/snacks/meat.dm +++ b/code/modules/reagents/reagent_containers/food/snacks/meat.dm @@ -9,7 +9,7 @@ reagents.add_reagent("nutriment", 3) src.bitesize = 3 -/obj/item/weapon/reagent_containers/food/snacks/meat/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/reagent_containers/food/snacks/meat/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/kitchen/utensil/knife)) new /obj/item/weapon/reagent_containers/food/snacks/rawcutlet(src) new /obj/item/weapon/reagent_containers/food/snacks/rawcutlet(src) @@ -35,3 +35,7 @@ /obj/item/weapon/reagent_containers/food/snacks/meat/corgi name = "Corgi meat" desc = "Tastes like... well you know..." + +/obj/item/weapon/reagent_containers/food/snacks/meat/pug + name = "Pug meat" + desc = "Tastes like... well you know..." \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index 0d1b64dacd3..4b070675231 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -12,7 +12,7 @@ amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,25,30,50) volume = 50 - flags = FPRINT | TABLEPASS | OPENCONTAINER + flags = OPENCONTAINER var/label_text = "" @@ -158,7 +158,7 @@ spawn(5) src.reagents.clear_reagents() return - attackby(obj/item/weapon/W as obj, mob/user as mob) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if(istype(W, /obj/item/weapon/pen) || istype(W, /obj/item/device/flashlight/pen)) var/tmp_label = sanitize(input(user, "Enter a label for [src.name]","Label",src.label_text)) @@ -226,11 +226,11 @@ name = "large beaker" desc = "A large beaker. Can hold up to 100 units." icon_state = "beakerlarge" - g_amt = 5000 + g_amt = 2500 volume = 100 amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,25,30,50,100) - flags = FPRINT | TABLEPASS | OPENCONTAINER + flags = OPENCONTAINER /obj/item/weapon/reagent_containers/glass/beaker/vial name = "vial" @@ -240,7 +240,7 @@ volume = 25 amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,25) - flags = FPRINT | TABLEPASS | OPENCONTAINER + flags = OPENCONTAINER /obj/item/weapon/reagent_containers/glass/beaker/noreact name = "cryostasis beaker" @@ -249,7 +249,7 @@ g_amt = 500 volume = 50 amount_per_transfer_from_this = 10 - flags = FPRINT | TABLEPASS | OPENCONTAINER | NOREACT + flags = OPENCONTAINER | NOREACT /obj/item/weapon/reagent_containers/glass/beaker/bluespace name = "bluespace beaker" @@ -259,7 +259,7 @@ volume = 300 amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,25,30,50,100,300) - flags = FPRINT | TABLEPASS | OPENCONTAINER + flags = OPENCONTAINER /obj/item/weapon/reagent_containers/glass/beaker/cryoxadone New() @@ -291,15 +291,17 @@ amount_per_transfer_from_this = 20 possible_transfer_amounts = list(5,10,15,25,30,50,80,100,120) volume = 120 - flags = FPRINT | OPENCONTAINER + flags = OPENCONTAINER - attackby(var/obj/D, mob/user as mob) + attackby(var/obj/D, mob/user as mob, params) if(isprox(D)) user << "You add [D] to [src]." del(D) user.put_in_hands(new /obj/item/weapon/bucket_sensor) - user.drop_from_inventory(src) - del(src) + user.unEquip(src) + qdel(src) + + ..() /obj/item/weapon/reagent_containers/glass/beaker/vial name = "vial" @@ -309,7 +311,7 @@ volume = 15 amount_per_transfer_from_this = 5 possible_transfer_amounts = list(1,5,15) - flags = FPRINT | TABLEPASS | OPENCONTAINER + flags = OPENCONTAINER /* /obj/item/weapon/reagent_containers/glass/blender_jug @@ -341,7 +343,6 @@ amount_per_transfer_from_this = 20 possible_transfer_amounts = list(10,20,30,60) volume = 120 - flags = FPRINT /obj/item/weapon/reagent_containers/glass/dispenser name = "reagent glass" @@ -349,7 +350,7 @@ icon = 'icons/obj/chemical.dmi' icon_state = "beaker0" amount_per_transfer_from_this = 10 - flags = FPRINT | TABLEPASS | OPENCONTAINER + flags = OPENCONTAINER /obj/item/weapon/reagent_containers/glass/dispenser/surfactant name = "reagent glass (surfactant)" diff --git a/code/modules/reagents/reagent_containers/glass/bottle.dm b/code/modules/reagents/reagent_containers/glass/bottle.dm index 419abe144c1..5c903608707 100644 --- a/code/modules/reagents/reagent_containers/glass/bottle.dm +++ b/code/modules/reagents/reagent_containers/glass/bottle.dm @@ -9,7 +9,7 @@ item_state = "atoxinbottle" amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,25,30) - flags = FPRINT | TABLEPASS | OPENCONTAINER + flags = OPENCONTAINER volume = 30 New() diff --git a/code/modules/reagents/reagent_containers/glass/bottle/robot.dm b/code/modules/reagents/reagent_containers/glass/bottle/robot.dm index 9286e5ab03b..7c8bf02a5bb 100644 --- a/code/modules/reagents/reagent_containers/glass/bottle/robot.dm +++ b/code/modules/reagents/reagent_containers/glass/bottle/robot.dm @@ -2,7 +2,7 @@ /obj/item/weapon/reagent_containers/glass/bottle/robot amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,25,30,50,100) - flags = FPRINT | TABLEPASS | OPENCONTAINER + flags = OPENCONTAINER volume = 60 var/reagent = "" diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index cd0a0cca72f..f9d1adfb1a6 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -12,20 +12,21 @@ amount_per_transfer_from_this = 5 volume = 30 possible_transfer_amounts = list(1,2,3,4,5,10,15,20,25,30) - flags = FPRINT | TABLEPASS | OPENCONTAINER + flags = OPENCONTAINER slot_flags = SLOT_BELT + var/ignore_flags = 0 /obj/item/weapon/reagent_containers/hypospray/attack_paw(mob/user as mob) return src.attack_hand(user) -/obj/item/weapon/reagent_containers/hypospray/attack(mob/M as mob, mob/user as mob) +/obj/item/weapon/reagent_containers/hypospray/attack(mob/living/M, mob/user) if(!reagents.total_volume) user << "\red [src] is empty." return - if (!( istype(M, /mob) )) + if(!istype(M)) return - if (reagents.total_volume) + if(reagents.total_volume && (ignore_flags || M.can_inject(user, 1))) user << "\blue You inject [M] with [src]." M << "\red You feel a tiny prick!" @@ -61,11 +62,20 @@ possible_transfer_amounts = list(10) icon_state = "combat_hypo" volume = 60 + ignore_flags = 1 // So they can heal their comrades. /obj/item/weapon/reagent_containers/hypospray/combat/New() ..() reagents.add_reagent("synaptizine", 30) +/obj/item/weapon/reagent_containers/hypospray/combat/nanites + name = "combat stimulant injector" + desc = "A modified air-needle autoinjector filled with expensive regeneration nanites." + volume = 100 + +/obj/item/weapon/reagent_containers/hypospray/combat/New() + ..() + reagents.add_reagent("nanites", 70) /obj/item/weapon/reagent_containers/hypospray/autoinjector name = "emergency autoinjector" @@ -75,6 +85,7 @@ amount_per_transfer_from_this = 10 possible_transfer_amounts = list(10) volume = 10 + ignore_flags = 1 //so you can medipen through hardsuits flags = null /obj/item/weapon/reagent_containers/hypospray/autoinjector/New() diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index e7b4ddf987f..5f4bdc09166 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -27,7 +27,7 @@ return M << "\blue You swallow [src]." - M.drop_from_inventory(src) //icon update + M.unEquip(src) //icon update if(reagents.total_volume) reagents.reaction(M, INGEST) spawn(5) @@ -49,7 +49,7 @@ if(!do_mob(user, M)) return - user.drop_from_inventory(src) //icon update + user.unEquip(src) //icon update for(var/mob/O in viewers(world.view, user)) O.show_message("\red [user] forces [M] to swallow [src].", 1) @@ -195,7 +195,7 @@ New() ..() reagents.add_reagent("paroxetine", 15) - + /obj/item/weapon/reagent_containers/pill/inaprovaline name = "Inaprovaline pill" desc = "Used to stabilize patients." diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 4f53ce68f19..17bbf565dfd 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/janitor.dmi' icon_state = "cleaner" item_state = "cleaner" - flags = TABLEPASS|OPENCONTAINER|FPRINT|NOBLUDGEON + flags = OPENCONTAINER | NOBLUDGEON slot_flags = SLOT_BELT throwforce = 0 w_class = 2.0 @@ -46,7 +46,8 @@ spray(A) playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6) - + user.changeNext_move(CLICK_CD_RANGE*2) + if(reagents.has_reagent("sacid")) message_admins("[key_name_admin(user)] fired sulphuric acid from \a [src].") log_game("[key_name(user)] fired sulphuric acid from \a [src].") diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index a7332fc5b92..7554c15630c 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -47,7 +47,7 @@ attack_paw() return attack_hand() - attackby(obj/item/I as obj, mob/user as mob) + attackby(obj/item/I as obj, mob/user as mob, params) return @@ -55,15 +55,20 @@ if(!proximity) return if(!target.reagents) return + if(isliving(target)) + var/mob/living/M = target + if(!M.can_inject(user, 1)) + return + if(mode == SYRINGE_BROKEN) user << "\red This syringe is broken!" return - if (user.a_intent == "harm" && ismob(target)) - if((M_CLUMSY in user.mutations) && prob(50)) +/* if (user.a_intent == "harm" && ismob(target)) + if((CLUMSY in user.mutations) && prob(50)) target = user syringestab(target, user) - return + return */ switch(mode) @@ -86,10 +91,27 @@ if(!T.dna) usr << "You are unable to locate any blood. (To be specific, your target seems to be missing their DNA datum)" return - if(M_NOCLONE in T.mutations) //target done been et, no more blood in him + if(NOCLONE in T.mutations) //target done been et, no more blood in him user << "\red You are unable to locate any blood." return + + var/time = 30 //Injecting through a hardsuit takes longer due to needing to find a port. + if(istype(target,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = T + if((H.species.bloodflags & BLOOD_SLIME) || (H.species.flags & NO_BLOOD)) + usr << "You are unable to locate any blood." + return + if(H.wear_suit && istype(H.wear_suit,/obj/item/clothing/suit/space)) + time = 60 + if(target == user) + time = 0 + else + for(var/mob/O in viewers(world.view, user)) + O.show_message(text("\red [] is trying to take a blood sample from []!", user, target), 1) + if(!do_mob(user, target, time)) + return + var/datum/reagent/B if(istype(T,/mob/living/carbon/human)) var/mob/living/carbon/human/H = T @@ -105,9 +127,10 @@ src.reagents.update_total() src.on_reagent_change() src.reagents.handle_reactions() - user << "\blue You take a blood sample from [target]" - for(var/mob/O in viewers(4, user)) - O.show_message("\red [user] takes a blood sample from [target].", 1) + + user << "\blue You take a blood sample from [target]" + for(var/mob/O in viewers(4, user)) + O.show_message("\red [user] takes a blood sample from [target].", 1) else //if not mob if(!target.reagents.total_volume) @@ -276,7 +299,7 @@ if (target != user && target.getarmor(target_zone, "melee") > 5 && prob(50)) for(var/mob/O in viewers(world.view, user)) O.show_message(text("\red [user] tries to stab [target] in \the [hit_area] with [src.name], but the attack is deflected by armor!"), 1) - user.u_equip(src) + user.unEquip(src) del(src) return diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index b95ea0c97a9..95d8694c449 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -7,13 +7,12 @@ icon_state = "watertank" density = 1 anchored = 0 - flags = FPRINT pressure_resistance = 2*ONE_ATMOSPHERE var/amount_per_transfer_from_this = 10 var/possible_transfer_amounts = list(10,25,50,100) - attackby(obj/item/weapon/W as obj, mob/user as mob) + attackby(obj/item/weapon/W as obj, mob/user as mob, params) return New() @@ -127,7 +126,7 @@ rig = null overlays = new/list() -/obj/structure/reagent_dispensers/fueltank/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/reagent_dispensers/fueltank/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W,/obj/item/weapon/wrench)) user.visible_message("[user] wrenches [src]'s faucet [modded ? "closed" : "open"].", \ "You wrench [src]'s faucet [modded ? "closed" : "open"]") @@ -144,7 +143,7 @@ var/obj/item/device/assembly_holder/H = W if (istype(H.a_left,/obj/item/device/assembly/igniter) || istype(H.a_right,/obj/item/device/assembly/igniter)) - message_admins("[key_name_admin(user)] rigged fueltank at ([loc.x],[loc.y],[loc.z]) for explosion.") + msg_admin_attack("[key_name_admin(user)] rigged fueltank at ([loc.x],[loc.y],[loc.z]) for explosion.") log_game("[key_name(user)] rigged fueltank at ([loc.x],[loc.y],[loc.z]) for explosion.") rig = W diff --git a/code/modules/reagents/syringe_gun.dm b/code/modules/reagents/syringe_gun.dm index d869c2b4899..965110d220b 100644 --- a/code/modules/reagents/syringe_gun.dm +++ b/code/modules/reagents/syringe_gun.dm @@ -1,136 +1,67 @@ - - - /obj/item/weapon/gun/syringe name = "syringe gun" - desc = "A spring loaded rifle designed to fit syringes, designed to incapacitate unruly patients from a distance." - icon = 'icons/obj/gun.dmi' + desc = "A spring loaded rifle designed to fit syringes, used to incapacitate unruly patients from a distance." icon_state = "syringegun" item_state = "syringegun" - w_class = 3.0 + w_class = 3 throw_speed = 2 throw_range = 10 - force = 4.0 - var/list/syringes = new/list() - var/max_syringes = 1 + force = 4 m_amt = 2000 + clumsy_check = 0 + fire_sound = 'sound/items/syringeproj.ogg' + var/list/syringes = list() + var/max_syringes = 1 + +/obj/item/weapon/gun/syringe/process_chambered() + if(!syringes.len) return 0 + + var/obj/item/weapon/reagent_containers/syringe/S = syringes[1] + + if(!S) return 0 + + in_chamber = new /obj/item/projectile/bullet/dart/syringe(src) + S.reagents.trans_to(in_chamber, S.reagents.total_volume) + in_chamber.name = S.name + syringes.Remove(S) + + del(S) + return 1 /obj/item/weapon/gun/syringe/examine() - set src in view() ..() - if (!(usr in view(2)) && usr!=src.loc) return - usr << "\blue [syringes.len] / [max_syringes] syringes." + usr << "Can hold [max_syringes] syringe\s. Has [syringes.len] syringe\s remaining." + return -/obj/item/weapon/gun/syringe/attackby(obj/item/I as obj, mob/user as mob) - if(istype(I, /obj/item/weapon/reagent_containers/syringe)) - var/obj/item/weapon/reagent_containers/syringe/S = I - if(S.mode != 2)//SYRINGE_BROKEN in syringes.dm - if(syringes.len < max_syringes) - user.drop_item() - I.loc = src - syringes += I - user << "\blue You put the syringe in [src]." - user << "\blue [syringes.len] / [max_syringes] syringes." - else - usr << "\red [src] cannot hold more syringes." +/obj/item/weapon/gun/syringe/attack_self(mob/living/user as mob) + if(!syringes.len) + user << "[src] is empty." + return 0 + + var/obj/item/weapon/reagent_containers/syringe/S = syringes[syringes.len] + + if(!S) return 0 + S.loc = user.loc + + syringes.Remove(S) + user << "You unload [S] from \the [src]!" + + return 1 + +/obj/item/weapon/gun/syringe/attackby(var/obj/item/A as obj, mob/user as mob, var/show_msg = 1, params) + if(istype(A, /obj/item/weapon/reagent_containers/syringe)) + if(syringes.len < max_syringes) + user.drop_item() + user << "You load [A] into \the [src]!" + syringes.Add(A) + A.loc = src + return 1 else - usr << "\red This syringe is broken!" - - -/obj/item/weapon/gun/syringe/afterattack(obj/target, mob/user , flag) - if(!isturf(target.loc) || target == user) return - ..() - -/obj/item/weapon/gun/syringe/can_fire() - return syringes.len - -/obj/item/weapon/gun/syringe/can_hit(var/mob/living/target as mob, var/mob/living/user as mob) - return 1 //SHOOT AND LET THE GOD GUIDE IT (probably will hit a wall anyway) - -/obj/item/weapon/gun/syringe/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) - if(syringes.len) - spawn(0) fire_syringe(target,user) - else - usr << "\red [src] is empty." - -/obj/item/weapon/gun/syringe/proc/fire_syringe(atom/target, mob/user) - if (locate (/obj/structure/table, src.loc)) - return - else - var/turf/trg = get_turf(target) - var/obj/effect/syringe_gun_dummy/D = new/obj/effect/syringe_gun_dummy(get_turf(src)) - var/obj/item/weapon/reagent_containers/syringe/S = syringes[1] - if((!S) || (!S.reagents)) //ho boy! wot runtimes! - return - S.reagents.trans_to(D, S.reagents.total_volume) - syringes -= S - del(S) - D.icon_state = "syringeproj" - D.name = "syringe" - playsound(user.loc, 'sound/items/syringeproj.ogg', 50, 1) - - for(var/i=0, i<6, i++) - if(!D) break - if(D.loc == trg) break - step_towards(D,trg) - - if(D) - for(var/mob/living/carbon/M in D.loc) - if(!istype(M,/mob/living/carbon)) continue - if(M == user) continue - //Syringe gun attack logging by Yvarov - var/R - if(D.reagents) - for(var/datum/reagent/A in D.reagents.reagent_list) - R += A.id + " (" - R += num2text(A.volume) + ")," - if (istype(M, /mob)) - M.attack_log += "\[[time_stamp()]\] [user]/[user.ckey] shot [M]/[M.ckey] with a syringegun ([R])" - user.attack_log += "\[[time_stamp()]\] [user]/[user.ckey] shot [M]/[M.ckey] with a syringegun ([R])" - if(M.ckey) - msg_admin_attack("[user] ([user.ckey]) shot [M] ([M.ckey]) with a syringegun ([R]) (JMP)") - if(!iscarbon(user)) - M.LAssailant = null - else - M.LAssailant = user - - else - M.attack_log += "\[[time_stamp()]\] UNKNOWN SUBJECT (No longer exists) shot [M]/[M.ckey] with a syringegun ([R])" - msg_admin_attack("UNKNOWN shot [M] ([M.ckey]) with a syringegun ([R]) (JMP)") - - if(D.reagents) - D.reagents.trans_to(M, 15) - M.visible_message("[M] is hit by the syringe!") - - del(D) - break - if(D) - for(var/atom/A in D.loc) - if(A == user) continue - if(A.density) del(D) - - sleep(1) - - if (D) spawn(10) del(D) - - return + usr << "[src] cannot hold more syringes." + return 0 /obj/item/weapon/gun/syringe/rapidsyringe name = "rapid syringe gun" - desc = "A modification of the syringe gun design, using a rotating cylinder to store up to four syringes." + desc = "A modification of the syringe gun design, using a rotating cylinder to store up to six syringes." icon_state = "rapidsyringegun" - max_syringes = 4 - - -/obj/effect/syringe_gun_dummy - name = "" - desc = "" - icon = 'icons/obj/chemical.dmi' - icon_state = "null" - anchored = 1 - density = 0 - - New() - var/datum/reagents/R = new/datum/reagents(15) - reagents = R - R.my_atom = src \ No newline at end of file + max_syringes = 6 \ No newline at end of file diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm index e784d8c0050..aa491bb823c 100644 --- a/code/modules/recycling/conveyor2.dm +++ b/code/modules/recycling/conveyor2.dm @@ -111,7 +111,7 @@ break // attack with item, place item on conveyor -/obj/machinery/conveyor/attackby(var/obj/item/I, mob/user) +/obj/machinery/conveyor/attackby(var/obj/item/I, mob/user, params) if(isrobot(user)) return //Carn: fix for borgs dropping their modules on conveyor belts user.drop_item() if(I && I.loc) I.loc = src.loc diff --git a/code/modules/recycling/disposal-construction.dm b/code/modules/recycling/disposal-construction.dm index e914d730c2d..fc6f51bf037 100644 --- a/code/modules/recycling/disposal-construction.dm +++ b/code/modules/recycling/disposal-construction.dm @@ -145,7 +145,7 @@ // wrench: (un)anchor // weldingtool: convert to real pipe - attackby(var/obj/item/I, var/mob/user) + attackby(var/obj/item/I, var/mob/user, params) var/nicetype = "pipe" var/ispipe = 0 // Indicates if we should change the level of this pipe src.add_fingerprint(user) diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 13740067ff2..8d2c573ce0e 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -43,8 +43,8 @@ // attack by item places it in to disposal - attackby(var/obj/item/I, var/mob/user) - if(stat & BROKEN || !I || !user) + attackby(var/obj/item/I, var/mob/user, params) + if(stat & BROKEN || !I || !user || (I.flags & NODROP)) return if(isrobot(user) && !istype(I, /obj/item/weapon/storage/bag/trash)) @@ -102,7 +102,7 @@ T.update_icon() update() return - + if(istype(I, /obj/item/weapon/storage/part_replacer)) var/obj/item/weapon/storage/part_replacer/P = I if(P.contents.len) @@ -111,7 +111,7 @@ P.remove_from_storage(O,src) update() return - + var/obj/item/weapon/grab/G = I if(istype(G)) // handle grabbed mob if(ismob(G.affecting)) @@ -238,6 +238,14 @@ return */ interact(user, 0) + + // hostile mob escape from disposals + attack_animal(var/mob/living/simple_animal/M) + if(M.environment_smash) + M.do_attack_animation(src) + visible_message("[M.name] smashes \the [src] apart!") + qdel(src) + return // user interaction interact(mob/user, var/ai=0) @@ -530,7 +538,7 @@ AM.loc = src if(istype(AM, /mob/living/carbon/human)) var/mob/living/carbon/human/H = AM - if(M_FAT in H.mutations) // is a human and fat? + if(FAT in H.mutations) // is a human and fat? has_fat_guy = 1 // set flag on holder if(istype(AM, /obj/structure/bigDelivery) && !hasmob) var/obj/structure/bigDelivery/T = AM @@ -861,7 +869,7 @@ //attack by item //weldingtool: unfasten and convert to obj/disposalconstruct - attackby(var/obj/item/I, var/mob/user) + attackby(var/obj/item/I, var/mob/user, params) var/turf/T = src.loc if(T.intact) @@ -1015,7 +1023,7 @@ update() return - attackby(var/obj/item/I, var/mob/user) + attackby(var/obj/item/I, var/mob/user, params) if(..()) return @@ -1162,7 +1170,7 @@ return // Override attackby so we disallow trunkremoval when somethings ontop -/obj/structure/disposalpipe/trunk/attackby(var/obj/item/I, var/mob/user) +/obj/structure/disposalpipe/trunk/attackby(var/obj/item/I, var/mob/user, params) //Disposal bins or chutes /* @@ -1300,7 +1308,7 @@ return - attackby(var/obj/item/I, var/mob/user) + attackby(var/obj/item/I, var/mob/user, params) if(!I || !user) return src.add_fingerprint(user) diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index a30e15a58ec..43772939fd0 100755 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -1,158 +1,189 @@ /obj/structure/bigDelivery - desc = "A big wrapped package." name = "large parcel" + desc = "A big wrapped package." icon = 'icons/obj/storage.dmi' icon_state = "deliverycloset" - var/obj/wrapped = null density = 1 - var/sortTag = 0 - flags = FPRINT | NOBLUDGEON mouse_drag_pointer = MOUSE_ACTIVE_POINTER + var/obj/wrapped = null + var/giftwrapped = 0 + var/sortTag = 0 - attack_hand(mob/user as mob) - if(wrapped) //sometimes items can disappear. For example, bombs. --rastaf0 - wrapped.loc = (get_turf(src.loc)) - if(istype(wrapped, /obj/structure/closet)) - var/obj/structure/closet/O = wrapped - O.welded = 0 - del(src) - return - attackby(obj/item/W as obj, mob/user as mob) - if(istype(W, /obj/item/device/destTagger)) - var/obj/item/device/destTagger/O = W +/obj/structure/bigDelivery/attack_hand(mob/user as mob) + qdel(src) - if(src.sortTag != O.currTag) - var/tag = uppertext(TAGGERLOCATIONS[O.currTag]) - user << "\blue *[tag]*" - src.sortTag = O.currTag - playsound(src.loc, 'sound/machines/twobeep.ogg', 100, 1) +/obj/structure/bigDelivery/Destroy() + if(wrapped) //sometimes items can disappear. For example, bombs. --rastaf0 + wrapped.loc = (get_turf(loc)) + if(istype(wrapped, /obj/structure/closet)) + var/obj/structure/closet/O = wrapped + O.welded = 0 + var/turf/T = get_turf(src) + for(var/atom/movable/AM in contents) + AM.loc = T + ..() + +/obj/structure/bigDelivery/attackby(obj/item/W as obj, mob/user as mob, params) + if(istype(W, /obj/item/device/destTagger)) + var/obj/item/device/destTagger/O = W + + if(sortTag != O.currTag) + var/tag = uppertext(TAGGERLOCATIONS[O.currTag]) + user << "*[tag]*" + sortTag = O.currTag + playsound(loc, 'sound/machines/twobeep.ogg', 100, 1) + + else if(istype(W, /obj/item/weapon/pen)) + var/str = copytext(sanitize(input(user,"Label text?","Set label","")),1,MAX_NAME_LEN) + if(!str || !length(str)) + user << "Invalid text." + return + user.visible_message("[user] labels [src] as [str].") + name = "[name] ([str])" + + else if(istype(W, /obj/item/stack/wrapping_paper) && !giftwrapped) + var/obj/item/stack/wrapping_paper/WP = W + if(WP.use(3)) + user.visible_message("[user] wraps the package in festive paper!") + giftwrapped = 1 + if(istype(wrapped, /obj/structure/closet/crate)) + icon_state = "giftcrate" + else + icon_state = "giftcloset" + if(WP.amount <= 0 && !WP.loc) //if we used our last wrapping paper, drop a cardboard tube + new /obj/item/weapon/c_tube( get_turf(user) ) + else + user << "You need more paper." - else if(istype(W, /obj/item/weapon/pen)) - var/str = copytext(sanitize(input(usr,"Label text?","Set label","")),1,MAX_NAME_LEN) - if(!str || !length(str)) - usr << "\red Invalid text." - return - for(var/mob/M in viewers()) - M << "\blue [user] labels [src] as [str]." - src.name = "[src.name] ([str])" - return /obj/item/smallDelivery - desc = "A small wrapped package." name = "small parcel" + desc = "A small wrapped package." icon = 'icons/obj/storage.dmi' icon_state = "deliverycrateSmall" var/obj/item/wrapped = null + var/giftwrapped = 0 var/sortTag = 0 - flags = FPRINT - attack_self(mob/user as mob) - if (src.wrapped) //sometimes items can disappear. For example, bombs. --rastaf0 - wrapped.loc = user.loc - if(ishuman(user)) - user.put_in_hands(wrapped) - else - wrapped.loc = get_turf_loc(src) +/obj/item/smallDelivery/attack_self(mob/user as mob) + if(wrapped && wrapped.loc) //sometimes items can disappear. For example, bombs. --rastaf0 + wrapped.loc = user.loc + if(ishuman(user)) + user.put_in_hands(wrapped) + else + wrapped.loc = get_turf(src) - del(src) - return - - attackby(obj/item/W as obj, mob/user as mob) - if(istype(W, /obj/item/device/destTagger)) - var/obj/item/device/destTagger/O = W - - if(src.sortTag != O.currTag) - var/tag = uppertext(TAGGERLOCATIONS[O.currTag]) - user << "\blue *[tag]*" - src.sortTag = O.currTag - playsound(src.loc, 'sound/machines/twobeep.ogg', 100, 1) - - else if(istype(W, /obj/item/weapon/pen)) - var/str = copytext(sanitize(input(usr,"Label text?","Set label","")),1,MAX_NAME_LEN) - if(!str || !length(str)) - usr << "\red Invalid text." - return - for(var/mob/M in viewers()) - M << "\blue [user] labels [src] as [str]." - src.name = "[src.name] ([str])" - return + qdel(src) -/obj/item/weapon/packageWrap +/obj/item/smallDelivery/attackby(obj/item/W as obj, mob/user as mob, params) + if(istype(W, /obj/item/device/destTagger)) + var/obj/item/device/destTagger/O = W + + if(sortTag != O.currTag) + var/tag = uppertext(TAGGERLOCATIONS[O.currTag]) + user << "*[tag]*" + sortTag = O.currTag + playsound(loc, 'sound/machines/twobeep.ogg', 100, 1) + + else if(istype(W, /obj/item/weapon/pen)) + var/str = copytext(sanitize(input(user,"Label text?","Set label","")),1,MAX_NAME_LEN) + if(!str || !length(str)) + user << "Invalid text." + return + user.visible_message("[user] labels [src] as [str].") + name = "[name] ([str])" + + else if(istype(W, /obj/item/stack/wrapping_paper) && !giftwrapped) + var/obj/item/stack/wrapping_paper/WP = W + if(WP.use(1)) + icon_state = "giftcrate[wrapped.w_class]" + giftwrapped = 1 + user.visible_message("[user] wraps the package in festive paper!") + if(WP.amount <= 0 && !WP.loc) //if we used our last wrapping paper, drop a cardboard tube + new /obj/item/weapon/c_tube( get_turf(user) ) + else + user << "You need more paper." + + + +/obj/item/stack/packageWrap name = "package wrapper" icon = 'icons/obj/items.dmi' icon_state = "deliveryPaper" - w_class = 3.0 - var/amount = 25.0 + flags = NOBLUDGEON + amount = 25 + max_amount = 25 - afterattack(var/obj/target as obj, mob/user as mob, proximity) - if(!proximity) return - if(!istype(target)) //this really shouldn't be necessary (but it is). -Pete - return - if(istype(target, /obj/item/smallDelivery) || istype(target,/obj/structure/bigDelivery) \ - || istype(target, /obj/item/weapon/gift) || istype(target, /obj/item/weapon/evidencebag)) - return - if(target.anchored) - return - if(target in user) - return - - user.attack_log += text("\[[time_stamp()]\] Has used [src.name] on \ref[target]") +/obj/item/stack/packageWrap/afterattack(var/obj/target as obj, mob/user as mob, proximity) + if(!proximity) return + if(!istype(target)) //this really shouldn't be necessary (but it is). -Pete + return + if(istype(target, /obj/item/smallDelivery) || istype(target,/obj/structure/bigDelivery) \ + || istype(target, /obj/item/weapon/evidencebag) || istype(target, /obj/structure/closet/body_bag)) + return + if(target.anchored) + return + if(target in user) + return - if (istype(target, /obj/item) && !(istype(target, /obj/item/weapon/storage) && !istype(target,/obj/item/weapon/storage/box))) - var/obj/item/O = target - if (src.amount > 1) - var/obj/item/smallDelivery/P = new /obj/item/smallDelivery(get_turf(O.loc)) //Aaannd wrap it up! - if(!istype(O.loc, /turf)) - if(user.client) - user.client.screen -= O - P.wrapped = O - O.loc = P - var/i = round(O.w_class) - if(i in list(1,2,3,4,5)) - P.icon_state = "deliverycrate[i]" - P.add_fingerprint(usr) - O.add_fingerprint(usr) - src.add_fingerprint(usr) - src.amount -= 1 - else if (istype(target, /obj/structure/closet/crate)) - var/obj/structure/closet/crate/O = target - if (src.amount > 3 && !O.opened) - var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc)) - P.icon_state = "deliverycrate" - P.wrapped = O - O.loc = P - src.amount -= 3 - else if(src.amount < 3) - user << "\blue You need more paper." - else if (istype (target, /obj/structure/closet)) - var/obj/structure/closet/O = target - if (src.amount > 3 && !O.opened) - var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc)) - P.wrapped = O - O.welded = 1 - O.loc = P - src.amount -= 3 - else if(src.amount < 3) - user << "\blue You need more paper." + + if(istype(target, /obj/item) && !(istype(target, /obj/item/weapon/storage) && !istype(target,/obj/item/weapon/storage/box))) + var/obj/item/O = target + if(use(1)) + var/obj/item/smallDelivery/P = new /obj/item/smallDelivery(get_turf(O.loc)) //Aaannd wrap it up! + if(!istype(O.loc, /turf)) + if(user.client) + user.client.screen -= O + P.wrapped = O + O.loc = P + var/i = round(O.w_class) + if(i in list(1,2,3,4,5)) + P.icon_state = "deliverycrate[i]" + P.w_class = i + P.add_fingerprint(usr) + O.add_fingerprint(usr) + add_fingerprint(usr) else - user << "\blue The object you are trying to wrap is unsuitable for the sorting machinery!" - if (src.amount <= 0) - new /obj/item/weapon/c_tube( src.loc ) - del(src) return + else if(istype(target, /obj/structure/closet/crate)) + var/obj/structure/closet/crate/O = target + if(O.opened) + return + if(use(3)) + var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc)) + P.icon_state = "deliverycrate" + P.wrapped = O + O.loc = P + else + user << "You need more paper." + return + else if(istype (target, /obj/structure/closet)) + var/obj/structure/closet/O = target + if(O.opened) + return + if(use(3)) + var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc)) + P.wrapped = O + O.welded = 1 + O.loc = P + else + user << "You need more paper." + return + else + user << "The object you are trying to wrap is unsuitable for the sorting machinery." return - examine() - if(src in usr) - usr << "\blue There are [amount] units of package wrap left!" - ..() - return + user.visible_message("[user] wraps [target].") + user.attack_log += text("\[[time_stamp()]\] Has used [name] on [target]") + if(amount <= 0 && !src.loc) //if we used our last wrapping paper, drop a cardboard tube + new /obj/item/weapon/c_tube( get_turf(user) ) + return /obj/item/device/destTagger name = "destination tagger" @@ -164,7 +195,7 @@ w_class = 1 item_state = "electronic" - flags = FPRINT | TABLEPASS | CONDUCT + flags = CONDUCT slot_flags = SLOT_BELT proc/openwindow(mob/user as mob) @@ -268,7 +299,7 @@ update() return - attackby(var/obj/item/I, var/mob/user) + attackby(var/obj/item/I, var/mob/user, params) if(!I || !user) return diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm index 237089dea5c..00b2af7cf5c 100644 --- a/code/modules/research/circuitprinter.dm +++ b/code/modules/research/circuitprinter.dm @@ -15,20 +15,20 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). var/diamond_amount = 0 var/max_material_amount = 75000.0 var/efficiency_coeff - + var/list/categories = list( "AI Modules", "Computer Boards", "Engineering Machinery", "Exosuit Modules", - "Hydroponics Machinery", + "Hydroponics Machinery", "Medical Machinery", "Misc. Machinery", "Research Machinery", "Subspace Telecomms", "Teleportation Machinery" ) - + reagents = new() /obj/machinery/r_n_d/circuit_imprinter/New() @@ -62,19 +62,19 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). /obj/machinery/r_n_d/circuit_imprinter/proc/check_mat(datum/design/being_built, var/M) switch(M) if("$glass") - return (g_amount - (being_built.materials[M]/efficiency_coeff) >= 0) ? 1 : 0 + return (g_amount - (being_built.materials[M]/efficiency_coeff) >= 0) if("$gold") - return (gold_amount - (being_built.materials[M]/efficiency_coeff) >= 0) ? 1 : 0 + return (gold_amount - (being_built.materials[M]/efficiency_coeff) >= 0) if("$diamond") - return (diamond_amount - (being_built.materials[M]/efficiency_coeff) >= 0) ? 1 : 0 + return (diamond_amount - (being_built.materials[M]/efficiency_coeff) >= 0) else - return (reagents.has_reagent(M, (being_built.materials[M]/efficiency_coeff)) != 0) ? 1 : 0 + return (reagents.has_reagent(M, (being_built.materials[M]/efficiency_coeff)) != 0) /obj/machinery/r_n_d/circuit_imprinter/proc/TotalMaterials() return g_amount + gold_amount + diamond_amount -/obj/machinery/r_n_d/circuit_imprinter/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/machinery/r_n_d/circuit_imprinter/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if (shocked) shock(user,50) if (default_deconstruction_screwdriver(user, "circuit_imprinter_t", "circuit_imprinter", O)) diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index 541518016b9..cd3acea26fe 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -19,7 +19,7 @@ category = list("initial","Tools") /datum/design/crowbar - name = "Pocket crowbar" + name = "Pocket Crowbar" id = "crowbar" build_type = AUTOLATHE materials = list("$metal" = 50) @@ -230,7 +230,7 @@ name = "Metal" id = "metal" build_type = AUTOLATHE - materials = list("$metal" = MINERAL_MATERIAL_AMOUNT) + materials = list("$metal" = 3750) build_path = /obj/item/stack/sheet/metal category = list("initial","Construction") @@ -254,7 +254,7 @@ name = "Reinforced Glass" id = "rglass" build_type = AUTOLATHE - materials = list("$metal" = 1000, "$glass" = MINERAL_MATERIAL_AMOUNT) + materials = list("$metal" = 1875, "$glass" = MINERAL_MATERIAL_AMOUNT) build_path = /obj/item/stack/sheet/rglass category = list("initial","Construction") @@ -262,7 +262,7 @@ name = "Metal Rod" id = "rods" build_type = AUTOLATHE - materials = list("$metal" = 1000) + materials = list("$metal" = 1875) build_path = /obj/item/stack/rods category = list("initial","Construction") @@ -440,7 +440,7 @@ id = "handcuffs" build_type = AUTOLATHE materials = list("$metal" = 500) - build_path = /obj/item/weapon/handcuffs + build_path = /obj/item/weapon/restraints/handcuffs category = list("hacked", "Security") /datum/design/incendiary_slug diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index 4567d00bfde..ab5653e0d1a 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -62,7 +62,7 @@ build_path = /obj/item/weapon/circuitboard/bodyscanner category = list("Medical Machinery") -/datum/design/sleep_console +/datum/design/bodyscanner_console name = "Machine Board (Body Scanner Console)" desc = "Allows for the construction of circuit boards used to build a Body Scanner Console." id = "bodyscanner_console" diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index 3f784559213..fe9acc74a7c 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -857,7 +857,8 @@ id = "borg_upgrade_jetpack" build_type = MECHFAB build_path = /obj/item/borg/upgrade/jetpack - materials = list("$metal"=10000,"$plasma"=15000,"$uranium" = 20000) + req_tech = list("engineering" = 4, "power" = 4) + materials = list("$metal"=10000, "$plasma"=5000, "$uranium" = 6000) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -866,6 +867,7 @@ id = "borg_upgrade_disablercooler" build_type = MECHFAB build_path = /obj/item/borg/upgrade/disablercooler + req_tech = list("combat" = 5, "power" = 4) materials = list("$metal"=80000 , "$glass"=6000 , "$gold"= 2000, "$diamond" = 500) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -902,7 +904,8 @@ id = "borg_upgrade_vtec" build_type = MECHFAB build_path = /obj/item/borg/upgrade/vtec - materials = list("$metal"=80000 , "$glass"=6000 , "$gold"= 5000) + req_tech = list("engineering" = 4, "materials" = 5) + materials = list("$metal"=80000 , "$glass"=6000 , "$uranium"= 5000) construction_time = 120 category = list("Cyborg Upgrade Modules") diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 3c4469f1859..b6b01c63872 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -11,7 +11,7 @@ reliability_base = 74 build_path = "/obj/item/device/mass_spectrometer/adv" category = list("Medical") - + /datum/design/adv_reagent_scanner name = "Advanced Reagent Scanner" desc = "A device for identifying chemicals and their proportions." @@ -22,18 +22,7 @@ reliability_base = 74 build_path = /obj/item/device/reagent_scanner/adv category = list("Medical") - -/datum/design/implant_chem - name = "Chemical Implant" - desc = "An implant which can be filled with various chemicals, and then injected on command." - id = "implant_chem" - req_tech = list("materials" = 2, "biotech" = 3) - build_type = PROTOLATHE - materials = list("$metal" = 50, "$glass" = 50) - build_path = /obj/item/weapon/implantcase/chem - locked = 1 - category = list("Medical") - + /datum/design/noreactbeaker name = "Cryostasis Beaker" desc = "A cryostasis beaker that allows for chemical storage without reactions. Can hold up to 50 units." @@ -44,7 +33,7 @@ reliability_base = 76 build_path = /obj/item/weapon/reagent_containers/glass/beaker/noreact category = list("Medical") - + /datum/design/cyborg_analyzer name = "Cyborg Analyzer" desc = "A hand-held scanner able to diagnose robotic injuries." @@ -52,10 +41,10 @@ req_tech = list("programming" = 2, "biotech" = 2, "magnets" = 2) build_type = PROTOLATHE materials = list("$metal" = 30, "$glass" = 20) - reliability_base = 74 + reliability_base = 76 build_path = /obj/item/device/robotanalyzer category = list("Medical") - + /datum/design/defib name = "Defibrillator" desc = "A device that delivers powerful shocks to detachable paddles that resuscitate incapacitated patients." @@ -66,38 +55,19 @@ reliability = 76 build_path = /obj/item/weapon/defibrillator category = list("Medical") - -/datum/design/implant_free - name = "Freedom Implant" - desc = "An implant which allows the user to instantly escape from restraints." - id = "implant_free" - req_tech = list("syndicate" = 2, "biotech" = 3) + + +/datum/design/sensor_device + name = "Handheld Crew Monitor" + desc = "A device for tracking crew members on the station." + id = "sensor_device" + req_tech = list("biotech" = 4, "magnets" = 3, "materials" = 3) build_type = PROTOLATHE - materials = list("$metal" = 50, "$glass" = 50) - build_path = /obj/item/weapon/implantcase/freedom + materials = list("$metal" = 30, "$glass" = 20) + reliability_base = 76 + build_path = /obj/item/device/sensor_device category = list("Medical") - -/datum/design/implanter - name = "Implanter" - desc = "A basic implanter for injecting implants" - id = "implanter" - req_tech = list("materials" = 2, "biotech" = 3) - build_type = PROTOLATHE - materials = list("$metal" = 50, "$glass" = 50) - build_path = "/obj/item/weapon/implanter" - category = list("Medical") - -/datum/design/implant_loyal - name = "Loyalty Implant" - desc = "An implant which makes its carrier loyal to Nanotrasen." - id = "implant_loyal" - req_tech = list("materials" = 2, "biotech" = 3) - build_type = PROTOLATHE - materials = list("$metal" = 7000, "$glass" = 7000) - build_path = /obj/item/weapon/implantcase/loyalty - locked = 1 - category = list("Medical") - + /datum/design/mmi name = "Man-Machine Interface" desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity." @@ -108,7 +78,7 @@ reliability_base = 76 build_path = /obj/item/device/mmi category = list("Misc","Medical") - + /datum/design/mass_spectrometer name = "Mass-Spectrometer" desc = "A device for analyzing chemicals in the blood." @@ -119,7 +89,7 @@ reliability_base = 76 build_path = /obj/item/device/mass_spectrometer category = list("Medical") - + /datum/design/posibrain name = "Positronic Brain" desc = "Allows for the construction of a positronic brain" @@ -140,7 +110,7 @@ reliability_base = 74 build_path = /obj/item/device/mmi/radio_enabled category = list("Misc","Medical") - + /datum/design/nanopaste name = "Nanopaste" desc = "A tube of paste containing swarms of repair nanites. Very effective in repairing robotic machinery." diff --git a/code/modules/research/designs/power_designs.dm b/code/modules/research/designs/power_designs.dm index 2b6efbff3fb..9edc8400e3e 100644 --- a/code/modules/research/designs/power_designs.dm +++ b/code/modules/research/designs/power_designs.dm @@ -9,7 +9,7 @@ req_tech = list("powerstorage" = 1) build_type = PROTOLATHE | AUTOLATHE | MECHFAB materials = list("$metal" = 700, "$glass" = 50) - build_path = /obj/item/weapon/cell + build_path = /obj/item/weapon/stock_parts/cell category = list("Misc","Power") /datum/design/high_cell @@ -19,7 +19,7 @@ req_tech = list("powerstorage" = 2) build_type = PROTOLATHE | AUTOLATHE | MECHFAB materials = list("$metal" = 700, "$glass" = 60) - build_path = /obj/item/weapon/cell/high + build_path = /obj/item/weapon/stock_parts/cell/high category = list("Misc","Power") /datum/design/hyper_cell @@ -30,7 +30,7 @@ reliability_base = 70 build_type = PROTOLATHE | MECHFAB materials = list("$metal" = 400, "$gold" = 150, "$silver" = 150, "$glass" = 70) - build_path = /obj/item/weapon/cell/hyper + build_path = /obj/item/weapon/stock_parts/cell/hyper category = list("Misc","Power") /datum/design/super_cell @@ -41,7 +41,7 @@ reliability_base = 75 build_type = PROTOLATHE | MECHFAB materials = list("$metal" = 700, "$glass" = 70) - build_path = /obj/item/weapon/cell/super + build_path = /obj/item/weapon/stock_parts/cell/super category = list("Misc","Power") /datum/design/pacman diff --git a/code/modules/research/designs/radio_pda_designs.dm b/code/modules/research/designs/radio_pda_designs.dm deleted file mode 100644 index 40dcac11da9..00000000000 --- a/code/modules/research/designs/radio_pda_designs.dm +++ /dev/null @@ -1,200 +0,0 @@ -///////////////////////////////////////// -/////////////PDA and Radio/////////////// -///////////////////////////////////////// -/datum/design/binaryencrypt - name = "Binary Encryption Key" - desc = "An encyption key for a radio headset. Contains cypherkeys." - id = "binaryencrypt" - req_tech = list("syndicate" = 2) - build_type = PROTOLATHE - materials = list("$metal" = 300, "$glass" = 300) - build_path = /obj/item/device/encryptionkey/binary - category = list("Communication") - -/datum/design/cart_atmos - name = "BreatheDeep Cartridge" - desc = "A data cartridge for portable microcomputers." - id = "cart_atmos" - req_tech = list("engineering" = 2, "powerstorage" = 3) - build_type = PROTOLATHE - materials = list("$metal" = 50, "$glass" = 50) - build_path = /obj/item/weapon/cartridge/atmos - category = list("Communication") - -/datum/design/cart_chemistry - name = "ChemWhiz Cartridge" - desc = "A data cartridge for portable microcomputers." - id = "cart_chemistry" - req_tech = list("engineering" = 2, "powerstorage" = 3) - build_type = PROTOLATHE - materials = list("$metal" = 50, "$glass" = 50) - build_path = /obj/item/weapon/cartridge/chemistry - category = list("Communication") - -/datum/design/cart_janitor - name = "CustodiPRO Cartridge" - desc = "A data cartridge for portable microcomputers." - id = "cart_janitor" - req_tech = list("engineering" = 2, "powerstorage" = 3) - build_type = PROTOLATHE - materials = list("$metal" = 50, "$glass" = 50) - build_path = /obj/item/weapon/cartridge/janitor - category = list("Communication") - -/datum/design/cart_mime - name = "Gestur-O 1000 Cartridge" - desc = "A data cartridge for portable microcomputers." - id = "cart_mime" - req_tech = list("engineering" = 2, "powerstorage" = 3) - build_type = PROTOLATHE - materials = list("$metal" = 50, "$glass" = 50) - build_path = /obj/item/weapon/cartridge/mime - category = list("Communication") - -/datum/design/cart_basic - name = "Generic Cartridge" - desc = "A data cartridge for portable microcomputers." - id = "cart_basic" - req_tech = list("engineering" = 2, "powerstorage" = 3) - build_type = PROTOLATHE - materials = list("$metal" = 50, "$glass" = 50) - build_path = /obj/item/weapon/cartridge - category = list("Communication") - -/datum/design/cart_clown - name = "Honkworks 5.0 Cartridge" - desc = "A data cartridge for portable microcomputers." - id = "cart_clown" - req_tech = list("engineering" = 2, "powerstorage" = 3) - build_type = PROTOLATHE - materials = list("$metal" = 50, "$glass" = 50) - build_path = /obj/item/weapon/cartridge/clown - category = list("Communication") - -/datum/design/cart_hop - name = "Human Resources 9001 Cartridge" - desc = "A data cartridge for portable microcomputers." - id = "cart_hop" - req_tech = list("engineering" = 2, "powerstorage" = 3) - build_type = PROTOLATHE - materials = list("$metal" = 50, "$glass" = 50) - build_path = /obj/item/weapon/cartridge/hop - locked = 1 - category = list("Communication") - -/datum/design/cart_medical - name = "Med-U Cartridge" - desc = "A data cartridge for portable microcomputers." - id = "cart_medical" - req_tech = list("engineering" = 2, "powerstorage" = 3) - build_type = PROTOLATHE - materials = list("$metal" = 50, "$glass" = 50) - build_path = /obj/item/weapon/cartridge/medical - category = list("Communication") - -/datum/design/cart_cmo - name = "Med-U DELUXE Cartridge" - desc = "A data cartridge for portable microcomputers." - id = "cart_cmo" - req_tech = list("engineering" = 2, "powerstorage" = 3) - build_type = PROTOLATHE - materials = list("$metal" = 50, "$glass" = 50) - build_path = /obj/item/weapon/cartridge/cmo - locked = 1 - category = list("Communication") - -/datum/design/pda - name = "PDA" - desc = "A portable microcomputer by Thinktronic Systems, LTD. Functionality determined by a preprogrammed ROM cartridge." - id = "pda" - req_tech = list("engineering" = 2, "powerstorage" = 3) - build_type = PROTOLATHE - materials = list("$metal" = 50, "$glass" = 50) - build_path = /obj/item/device/pda - category = list("Communication") - -/datum/design/cart_engineering - name = "Power-ON Cartridge" - desc = "A data cartridge for portable microcomputers." - id = "cart_engineering" - req_tech = list("engineering" = 2, "powerstorage" = 3) - build_type = PROTOLATHE - materials = list("$metal" = 50, "$glass" = 50) - build_path = /obj/item/weapon/cartridge/engineering - category = list("Communication") - -/datum/design/cart_ce - name = "Power-On DELUXE Cartridge" - desc = "A data cartridge for portable microcomputers." - id = "cart_ce" - req_tech = list("engineering" = 2, "powerstorage" = 3) - build_type = PROTOLATHE - materials = list("$metal" = 50, "$glass" = 50) - build_path = /obj/item/weapon/cartridge/ce - locked = 1 - category = list("Communication") - -/datum/design/cart_security - name = "R.O.B.U.S.T. Cartridge" - desc = "A data cartridge for portable microcomputers." - id = "cart_security" - req_tech = list("engineering" = 2, "powerstorage" = 3) - build_type = PROTOLATHE - materials = list("$metal" = 50, "$glass" = 50) - build_path = "/obj/item/weapon/cartridge/security" - locked = 1 - category = list("Communication") - -/datum/design/cart_hos - name = "R.O.B.U.S.T. DELUXE Cartridge" - desc = "A data cartridge for portable microcomputers." - id = "cart_hos" - req_tech = list("engineering" = 2, "powerstorage" = 3) - build_type = PROTOLATHE - materials = list("$metal" = 50, "$glass" = 50) - build_path = /obj/item/weapon/cartridge/hos - locked = 1 - category = list("Communication") - -/datum/design/cart_toxins - name = "Signal Ace 2 Cartridge" - desc = "A data cartridge for portable microcomputers." - id = "cart_toxins" - req_tech = list("engineering" = 2, "powerstorage" = 3) - build_type = PROTOLATHE - materials = list("$metal" = 50, "$glass" = 50) - build_path = /obj/item/weapon/cartridge/signal/toxins - category = list("Communication") - -/datum/design/cart_rd - name = "Signal Ace DELUXE Cartridge" - desc = "A data cartridge for portable microcomputers." - id = "cart_rd" - req_tech = list("engineering" = 2, "powerstorage" = 3) - build_type = PROTOLATHE - materials = list("$metal" = 50, "$glass" = 50) - build_path = /obj/item/weapon/cartridge/rd - locked = 1 - category = list("Communication") - -/datum/design/cart_quartermaster - name = "Space Parts & Space Vendors Cartridge" - desc = "A data cartridge for portable microcomputers." - id = "cart_quartermaster" - req_tech = list("engineering" = 2, "powerstorage" = 3) - build_type = PROTOLATHE - materials = list("$metal" = 50, "$glass" = 50) - build_path = /obj/item/weapon/cartridge/quartermaster - locked = 1 - category = list("Communication") - -/datum/design/cart_captain - name = "Value-PAK Cartridge" - desc = "A data cartridge for portable microcomputers." - id = "cart_captain" - req_tech = list("engineering" = 2, "powerstorage" = 3) - build_type = PROTOLATHE - materials = list("$metal" = 50, "$glass" = 50) - build_path = /obj/item/weapon/cartridge/captain - locked = 1 - category = list("Communication") \ No newline at end of file diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index 399f226e15c..2a892e2d057 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -6,7 +6,7 @@ name = "Advanced Energy Gun" desc = "An energy gun with an experimental miniaturized reactor." id = "nuclear_gun" - req_tech = list("combat" = 3, "materials" = 5, "powerstorage" = 3) + req_tech = list("combat" = 4, "materials" = 5, "powerstorage" = 3) build_type = PROTOLATHE materials = list("$metal" = 5000, "$glass" = 1000, "$uranium" = 2000) reliability_base = 76 @@ -68,6 +68,16 @@ build_path = /obj/item/weapon/grenade/chem_grenade/large category = list("Weapons") +/datum/design/tele_shield + name = "Telescopic Riot Shield" + desc = "An advanced riot shield made of lightweight materials that collapses for easy storage." + id = "tele_shield" + req_tech = list("combat" = 4, "materials" = 3, "engineering" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 4000, "$glass" = 5000, "$silver" = 300) + build_path = /obj/item/weapon/shield/riot/tele + category = list("Weapons") + /datum/design/lasercannon name = "Laser Cannon" desc = "A heavy duty laser cannon." @@ -79,6 +89,16 @@ locked = 1 category = list("Weapons") +/datum/design/receiver + name = "Modular Receiver" + desc = "A prototype modular receiver and trigger assembly for a variety of firearms." + id = "receiver" + req_tech = list("combat" = 5, "materials" = 4) + build_type = PROTOLATHE + materials = list("$metal" = 6500, "$silver" = 500) + build_path = /obj/item/weaponcrafting/receiver + category = list("Weapons") + /datum/design/plasmapistol name = "Plasma Pistol" desc = "A specialized firearm designed to fire lethal bolts of toxins." @@ -119,7 +139,6 @@ build_type = PROTOLATHE materials = list("$metal" = 5000, "$glass" = 1000) build_path = /obj/item/weapon/gun/syringe/rapidsyringe - locked = 1 category = list("Weapons") /datum/design/stunshell @@ -138,7 +157,7 @@ id = "stunrevolver" req_tech = list("combat" = 3, "materials" = 3, "powerstorage" = 2) build_type = PROTOLATHE - materials = list("$metal" = 4000) + materials = list("$metal" = 4000, "$glass" = 1000) build_path = /obj/item/weapon/gun/energy/stunrevolver locked = 1 category = list("Weapons") diff --git a/code/modules/research/destructive_analyzer.dm b/code/modules/research/destructive_analyzer.dm index 3bbdb2f2db6..57f36ad9179 100644 --- a/code/modules/research/destructive_analyzer.dm +++ b/code/modules/research/destructive_analyzer.dm @@ -37,7 +37,7 @@ Note: Must be placed within 3 tiles of the R&D Console return temp_list -/obj/machinery/r_n_d/destructive_analyzer/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/machinery/r_n_d/destructive_analyzer/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if (shocked) shock(user,50) if (default_deconstruction_screwdriver(user, "d_analyzer_t", "d_analyzer", O)) diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm index b1ddc3eb62a..09a2b9a7974 100644 --- a/code/modules/research/protolathe.dm +++ b/code/modules/research/protolathe.dm @@ -26,17 +26,16 @@ Note: Must be placed west/left of and R&D console to function. var/list/categories = list( "Bluespace", - "Communication", "Equipment", "Janitorial", "Medical", "Mining", "Miscellaneous", "Power", - "Stock Parts", - "Weapons" - ) - + "Stock Parts", + "Weapons" + ) + reagents = new() @@ -93,7 +92,7 @@ Note: Must be placed west/left of and R&D console to function. A = A / max(1, (being_built.materials[M]/efficiency_coeff)) return A -/obj/machinery/r_n_d/protolathe/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/machinery/r_n_d/protolathe/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if (shocked) shock(user,50) if (default_deconstruction_screwdriver(user, "protolathe_t", "protolathe", O)) @@ -199,8 +198,9 @@ Note: Must be placed west/left of and R&D console to function. busy = 0 src.updateUsrDialog() - src.overlays += "protolathe_[stack.name]" - sleep(10) - src.overlays -= "protolathe_[stack.name]" + if(stack) + src.overlays += "protolathe_[stack.name]" + sleep(10) + src.overlays -= "protolathe_[stack.name]" return diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 6cd7c7471b1..d901423368b 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -50,7 +50,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, req_access = list(access_research) //Data and setting manipulation requires scientist access. var/selected_category - + var/list/datum/design/matching_designs = list() //for the search function /obj/machinery/computer/rdconsole/proc/CallTechName(var/ID) //A simple helper proc to find the name of a tech with a given ID. var/datum/tech/check_tech @@ -130,11 +130,12 @@ won't update every console in existence) but it's more of a hassle to do. Also, files.known_tech=files.possible_tech for(var/datum/tech/KT in files.known_tech) if(KT.level < KT.max_level) - KT.level=KT.max_level - + KT.level=KT.max_level + /obj/machinery/computer/rdconsole/New() ..() files = new /datum/research(src) //Setup the research data holder. + matching_designs = list() if(!id) for(var/obj/machinery/r_n_d/server/centcom/S in world) S.initialize() @@ -148,7 +149,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, griefProtection() */ -/obj/machinery/computer/rdconsole/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob) +/obj/machinery/computer/rdconsole/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob, params) //Loading a disk into it. if(istype(D, /obj/item/weapon/disk)) @@ -164,16 +165,17 @@ won't update every console in existence) but it's more of a hassle to do. Also, user.drop_item() D.loc = src user << " You add the disk to the machine!" - else if(istype(D,/obj/item/weapon/card/emag)) - if(!emagged) - playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) - emagged = 1 - user << "You you disable the security protocols" else ..() src.updateUsrDialog() return +/obj/machinery/computer/rdconsole/emag_act(user as mob) + if(!emagged) + playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) + emagged = 1 + user << "You disable the security protocols" + /obj/machinery/computer/rdconsole/Topic(href, href_list) if(..()) return @@ -206,7 +208,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, t_disk = null screen = 1.0 - else if(href_list["copy_tech"]) //Copys some technology data from the research holder to the disk. + else if(href_list["copy_tech"]) //Copy some technology data from the research holder to the disk. for(var/datum/tech/T in files.known_tech) if(href_list["copy_tech_ID"] == T.id) t_disk.stored = T @@ -248,11 +250,12 @@ won't update every console in existence) but it's more of a hassle to do. Also, linked_destroy.loaded_item = null linked_destroy.icon_state = "d_analyzer" screen = 2.1 - + else if(href_list["maxresearch"]) //Eject the item inside the destructive analyzer. if(!usr.client.holder) return + if(usr.client.holder & R_MENTOR) return screen = 0.0 - if(alert("Are you sure you want to maximize research levels?","Confirmation","Yes","No")=="No") + if(alert("Are you sure you want to maximize research levels?","Confirmation","Yes","No")=="No") return log_admin("[key_name(usr)] has maximized the research levels.") message_admins("[key_name_admin(usr)] has maximized the research levels.") @@ -260,7 +263,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, Maximize() screen = 1.0 updateUsrDialog() - griefProtection() //Update centcomm too + griefProtection() //Update centcomm too else if(href_list["deconstruct"]) //Deconstruct the item in the destructive analyzer and update the research holder. if(linked_destroy) @@ -370,6 +373,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, if(being_built) var/power = 2000 var/amount=text2num(href_list["amount"]) + var/old_screen = screen amount = max(1, min(10, amount)) for(var/M in being_built.materials) power += round(being_built.materials[M] * amount / 5) @@ -385,34 +389,38 @@ won't update every console in existence) but it's more of a hassle to do. Also, if (g2g) //If input is incorrect, nothing happens + var/enough_materials = 1 linked_lathe.busy = 1 flick("protolathe_n",linked_lathe) use_power(power) for(var/M in being_built.materials) - if(!linked_lathe.check_mat(being_built, M)) + if(linked_lathe.check_mat(being_built, M) < amount) src.visible_message("The [src.name] beeps, \"Not enough materials to complete prototype.\"") + enough_materials = 0 g2g = 0 break - switch(M) - if("$metal") - linked_lathe.m_amount = max(0, (linked_lathe.m_amount-(being_built.materials[M]/coeff * amount))) - if("$glass") - linked_lathe.g_amount = max(0, (linked_lathe.g_amount-(being_built.materials[M]/coeff * amount))) - if("$gold") - linked_lathe.gold_amount = max(0, (linked_lathe.gold_amount-(being_built.materials[M]/coeff * amount))) - if("$silver") - linked_lathe.silver_amount = max(0, (linked_lathe.silver_amount-(being_built.materials[M]/coeff * amount))) - if("$plasma") - linked_lathe.plasma_amount = max(0, (linked_lathe.plasma_amount-(being_built.materials[M]/coeff * amount))) - if("$uranium") - linked_lathe.uranium_amount = max(0, (linked_lathe.uranium_amount-(being_built.materials[M]/coeff * amount))) - if("$diamond") - linked_lathe.diamond_amount = max(0, (linked_lathe.diamond_amount-(being_built.materials[M]/coeff * amount))) - if("$bananium") - linked_lathe.clown_amount = max(0, (linked_lathe.clown_amount-(being_built.materials[M]/coeff * amount))) - else - linked_lathe.reagents.remove_reagent(M, being_built.materials[M]/coeff * amount) + if(enough_materials) + for(var/M in being_built.materials) + switch(M) + if("$metal") + linked_lathe.m_amount = max(0, (linked_lathe.m_amount-(being_built.materials[M]/coeff * amount))) + if("$glass") + linked_lathe.g_amount = max(0, (linked_lathe.g_amount-(being_built.materials[M]/coeff * amount))) + if("$gold") + linked_lathe.gold_amount = max(0, (linked_lathe.gold_amount-(being_built.materials[M]/coeff * amount))) + if("$silver") + linked_lathe.silver_amount = max(0, (linked_lathe.silver_amount-(being_built.materials[M]/coeff * amount))) + if("$plasma") + linked_lathe.plasma_amount = max(0, (linked_lathe.plasma_amount-(being_built.materials[M]/coeff * amount))) + if("$uranium") + linked_lathe.uranium_amount = max(0, (linked_lathe.uranium_amount-(being_built.materials[M]/coeff * amount))) + if("$diamond") + linked_lathe.diamond_amount = max(0, (linked_lathe.diamond_amount-(being_built.materials[M]/coeff * amount))) + if("$bananium") + linked_lathe.clown_amount = max(0, (linked_lathe.clown_amount-(being_built.materials[M]/coeff * amount))) + else + linked_lathe.reagents.remove_reagent(M, being_built.materials[M]/coeff * amount) var/P = being_built.build_path //lets save these values before the spawn() just in case. Nobody likes runtimes. var/R = being_built.reliability @@ -435,7 +443,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, else new_item.loc = linked_lathe.loc linked_lathe.busy = 0 - screen = 3.15 + screen = old_screen updateUsrDialog() else if(href_list["imprint"]) //Causes the Circuit Imprinter to build something. @@ -449,6 +457,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, break if(being_built) var/power = 2000 + var/old_screen = screen for(var/M in being_built.materials) power += round(being_built.materials[M] / 5) power = max(2000, power) @@ -487,7 +496,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, new_item.reliability = R new_item.loc = linked_imprinter.loc linked_imprinter.busy = 0 - screen = 4.1 + screen = old_screen updateUsrDialog() else if(href_list["disposeI"] && linked_imprinter) //Causes the circuit imprinter to dispose of a single reagent (all of it) @@ -589,6 +598,25 @@ won't update every console in existence) but it's more of a hassle to do. Also, spawn(20) screen = 1.6 updateUsrDialog() + + else if(href_list["search"]) //Search for designs with name matching pattern + var/compare + + matching_designs.Cut() + + if(href_list["type"] == "proto") + compare = PROTOLATHE + screen = 3.17 + else + compare = IMPRINTER + screen = 4.17 + + for(var/datum/design/D in files.known_designs) + if(!(D.build_type & compare)) + continue + if(findtext(D.name,href_list["to_search"])) + matching_designs.Add(D) + updateUsrDialog() return @@ -801,7 +829,15 @@ won't update every console in existence) but it's more of a hassle to do. Also, dat += "Chemical Storage
" dat += "

Protolathe Menu:


" dat += "Material Amount: [linked_lathe.TotalMaterials()] / [linked_lathe.max_material_storage]
" - dat += "Chemical Volume: [linked_lathe.reagents.total_volume] / [linked_lathe.reagents.maximum_volume]
" + dat += "Chemical Volume: [linked_lathe.reagents.total_volume] / [linked_lathe.reagents.maximum_volume]
" + + dat += "
\ + \ + \ + \ + \ + \ +

" dat += list_categories(linked_lathe.categories, 3.15) @@ -823,17 +859,17 @@ won't update every console in existence) but it's more of a hassle to do. Also, for(var/M in D.materials) t = linked_lathe.check_mat(D, M) temp_material += " | " - if (!t) + if (t < 1) temp_material += "[D.materials[M]/coeff] [CallMaterialName(M)]" else temp_material += " [D.materials[M]/coeff] [CallMaterialName(M)]" c = min(c,t) - if (c) + if (c >= 1) dat += "[D.name]" - if(c >= 5.0) + if(c >= 5) dat += "x5" - if(c >= 10.0) + if(c >= 10) dat += "x10" dat += "[temp_material]" else @@ -843,6 +879,39 @@ won't update every console in existence) but it's more of a hassle to do. Also, dat += "
" dat += "
" + if(3.17) //Display search result + dat += "Main Menu" + dat += "Protolathe Menu" + dat += "

Search results:


" + dat += "Material Amount: [linked_lathe.TotalMaterials()] / [linked_lathe.max_material_storage]
" + dat += "Chemical Volume: [linked_lathe.reagents.total_volume] / [linked_lathe.reagents.maximum_volume]
" + + var/coeff = linked_lathe.efficiency_coeff + for(var/datum/design/D in matching_designs) + var/temp_material + var/c = 50 + var/t + for(var/M in D.materials) + t = linked_lathe.check_mat(D, M) + temp_material += " | " + if (t < 1) + temp_material += "[D.materials[M]/coeff] [CallMaterialName(M)]" + else + temp_material += " [D.materials[M]/coeff] [CallMaterialName(M)]" + c = min(c,t) + + if (c >= 1) + dat += "[D.name]" + if(c >= 5) + dat += "x5" + if(c >= 10) + dat += "x10" + dat += "[temp_material]" + else + dat += "[D.name][temp_material]" + dat += "
" + dat += "
" + if(3.2) //Protolathe Material Storage Sub-menu dat += "Main Menu" dat += "Protolathe Menu
" @@ -918,6 +987,14 @@ won't update every console in existence) but it's more of a hassle to do. Also, dat += "Material Amount: [linked_imprinter.TotalMaterials()]
" dat += "Chemical Volume: [linked_imprinter.reagents.total_volume]
" + dat += "
\ + \ + \ + \ + \ + \ +

" + dat += list_categories(linked_imprinter.categories, 4.15) if(4.15) @@ -948,6 +1025,30 @@ won't update every console in existence) but it's more of a hassle to do. Also, dat += " | LOCKED" dat += "
" + if(4.17) + dat += "Main Menu" + dat += "Circuit Imprinter Menu" + dat += "

Search results:


" + dat += "Material Amount: [linked_imprinter.TotalMaterials()]
" + dat += "Chemical Volume: [linked_imprinter.reagents.total_volume]
" + + var/coeff = linked_imprinter.efficiency_coeff + for(var/datum/design/D in matching_designs) + var/temp_materials + var/check_materials = 1 + for(var/M in D.materials) + temp_materials += " | " + if (!linked_imprinter.check_mat(D, M)) + check_materials = 0 + temp_materials += " [D.materials[M]/coeff] [CallMaterialName(M)]" + else + temp_materials += " [D.materials[M]/coeff] [CallMaterialName(M)]" + if (check_materials) + dat += "[D.name][temp_materials]
" + else + dat += "[D.name][temp_materials]
" + dat += "
" + if(4.2) dat += "Main Menu" dat += "Imprinter Menu" diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm index 109ab110d71..e3daebc6b36 100644 --- a/code/modules/research/server.dm +++ b/code/modules/research/server.dm @@ -118,7 +118,7 @@ env.merge(removed) -/obj/machinery/r_n_d/server/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/machinery/r_n_d/server/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if (disabled) return @@ -319,14 +319,12 @@ onclose(user, "server_control") return -/obj/machinery/computer/rdservercontrol/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob) - if(istype(D, /obj/item/weapon/card/emag) && !emagged) +/obj/machinery/computer/rdservercontrol/emag_act(user as mob) + if(!emagged) playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) emagged = 1 user << "\blue You you disable the security protocols" src.updateUsrDialog() - return ..() - /obj/machinery/r_n_d/server/robotics name = "Robotics R&D Server" diff --git a/code/modules/research/xenoarchaeology/artifact/artifact.dm b/code/modules/research/xenoarchaeology/artifact/artifact.dm index 1ba21f79667..0b12d5cf62a 100644 --- a/code/modules/research/xenoarchaeology/artifact/artifact.dm +++ b/code/modules/research/xenoarchaeology/artifact/artifact.dm @@ -64,10 +64,11 @@ if(istype(M.selected,/obj/item/mecha_parts/mecha_equipment/tool/drill)) M.selected.action(src) -/obj/structure/boulder/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/boulder/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/device/core_sampler)) - src.geological_data.artifact_distance = rand(-100,100) / 100 - src.geological_data.artifact_id = artifact_find.artifact_id + if(geological_data) + src.geological_data.artifact_distance = rand(-100,100) / 100 + src.geological_data.artifact_id = artifact_find.artifact_id var/obj/item/device/core_sampler/C = W C.sample_item(src, user) diff --git a/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm b/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm index 56954dc6dd1..9a2fad715cf 100644 --- a/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm +++ b/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm @@ -48,10 +48,10 @@ /obj/item/weapon/caution/cone,\ /obj/item/weapon/crowbar,\ /obj/item/weapon/clipboard,\ - /obj/item/weapon/cell,\ + /obj/item/weapon/stock_parts/cell,\ /obj/item/weapon/circular_saw,\ /obj/item/weapon/hatchet,\ - /obj/item/weapon/handcuffs,\ + /obj/item/weapon/restraints/handcuffs,\ /obj/item/weapon/hemostat,\ /obj/item/weapon/kitchenknife,\ /obj/item/weapon/lighter,\ @@ -128,7 +128,7 @@ user << browse(dat, "window=alien_replicator") -/obj/machinery/replicator/attackby(obj/item/weapon/W as obj, mob/living/user as mob) +/obj/machinery/replicator/attackby(obj/item/weapon/W as obj, mob/living/user as mob, params) user.drop_item() W.loc = src stored_materials.Add(W) diff --git a/code/modules/research/xenoarchaeology/artifact/artifact_unknown.dm b/code/modules/research/xenoarchaeology/artifact/artifact_unknown.dm index 98bb7a1cd8b..1351af58f79 100644 --- a/code/modules/research/xenoarchaeology/artifact/artifact_unknown.dm +++ b/code/modules/research/xenoarchaeology/artifact/artifact_unknown.dm @@ -244,7 +244,7 @@ var/list/valid_secondary_effect_types = list(\ if(secondary_effect && secondary_effect.effect == EFFECT_TOUCH && secondary_effect.activated) secondary_effect.DoEffectTouch(user) -/obj/machinery/artifact/attackby(obj/item/weapon/W as obj, mob/living/user as mob) +/obj/machinery/artifact/attackby(obj/item/weapon/W as obj, mob/living/user as mob, params) if (istype(W, /obj/item/weapon/reagent_containers/)) if(W.reagents.has_reagent("hydrogen", 1) || W.reagents.has_reagent("water", 1)) diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_cellcharge.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_cellcharge.dm index d7ff967c2d0..da7f1a012ee 100644 --- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_cellcharge.dm +++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_cellcharge.dm @@ -8,7 +8,7 @@ if(user) if(istype(user, /mob/living/silicon/robot)) var/mob/living/silicon/robot/R = user - for (var/obj/item/weapon/cell/D in R.contents) + for (var/obj/item/weapon/stock_parts/cell/D in R.contents) D.charge += rand() * 100 + 50 R << "\blue SYSTEM ALERT: Large energy boost detected!" return 1 @@ -17,12 +17,12 @@ if(holder) var/turf/T = get_turf(holder) for (var/obj/machinery/power/apc/C in range(200, T)) - for (var/obj/item/weapon/cell/B in C.contents) + for (var/obj/item/weapon/stock_parts/cell/B in C.contents) B.charge += 25 for (var/obj/machinery/power/smes/S in range (src.effectrange,src)) S.charge += 25 for (var/mob/living/silicon/robot/M in mob_list) - for (var/obj/item/weapon/cell/D in M.contents) + for (var/obj/item/weapon/stock_parts/cell/D in M.contents) D.charge += 25 M << "\blue SYSTEM ALERT: Energy boost detected!" return 1 @@ -31,12 +31,12 @@ if(holder) var/turf/T = get_turf(holder) for (var/obj/machinery/power/apc/C in range(200, T)) - for (var/obj/item/weapon/cell/B in C.contents) + for (var/obj/item/weapon/stock_parts/cell/B in C.contents) B.charge += rand() * 100 for (var/obj/machinery/power/smes/S in range (src.effectrange,src)) S.charge += 250 for (var/mob/living/silicon/robot/M in mob_list) - for (var/obj/item/weapon/cell/D in M.contents) + for (var/obj/item/weapon/stock_parts/cell/D in M.contents) D.charge += rand() * 100 M << "\blue SYSTEM ALERT: Energy boost detected!" return 1 diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_celldrain.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_celldrain.dm index 8af61035d49..025cdec5ee0 100644 --- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_celldrain.dm +++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_celldrain.dm @@ -8,7 +8,7 @@ if(user) if(istype(user, /mob/living/silicon/robot)) var/mob/living/silicon/robot/R = user - for (var/obj/item/weapon/cell/D in R.contents) + for (var/obj/item/weapon/stock_parts/cell/D in R.contents) D.charge = max(D.charge - rand() * 100, 0) R << "\blue SYSTEM ALERT: Energy drain detected!" return 1 @@ -19,12 +19,12 @@ if(holder) var/turf/T = get_turf(holder) for (var/obj/machinery/power/apc/C in range(200, T)) - for (var/obj/item/weapon/cell/B in C.contents) + for (var/obj/item/weapon/stock_parts/cell/B in C.contents) B.charge = max(B.charge - 50,0) for (var/obj/machinery/power/smes/S in range (src.effectrange,src)) S.charge = max(S.charge - 100,0) for (var/mob/living/silicon/robot/M in mob_list) - for (var/obj/item/weapon/cell/D in M.contents) + for (var/obj/item/weapon/stock_parts/cell/D in M.contents) D.charge = max(D.charge - 50,0) M << "\red SYSTEM ALERT: Energy drain detected!" return 1 @@ -33,12 +33,12 @@ if(holder) var/turf/T = get_turf(holder) for (var/obj/machinery/power/apc/C in range(200, T)) - for (var/obj/item/weapon/cell/B in C.contents) + for (var/obj/item/weapon/stock_parts/cell/B in C.contents) B.charge = max(B.charge - rand() * 150,0) for (var/obj/machinery/power/smes/S in range (src.effectrange,src)) S.charge = max(S.charge - 250,0) for (var/mob/living/silicon/robot/M in mob_list) - for (var/obj/item/weapon/cell/D in M.contents) + for (var/obj/item/weapon/stock_parts/cell/D in M.contents) D.charge = max(D.charge - rand() * 150,0) M << "\red SYSTEM ALERT: Energy drain detected!" return 1 diff --git a/code/modules/research/xenoarchaeology/chemistry.dm b/code/modules/research/xenoarchaeology/chemistry.dm index e4701247544..9bd0a22a9c2 100644 --- a/code/modules/research/xenoarchaeology/chemistry.dm +++ b/code/modules/research/xenoarchaeology/chemistry.dm @@ -87,9 +87,9 @@ datum amount_per_transfer_from_this = 1 possible_transfer_amounts = list(1, 2) volume = 2 - flags = FPRINT | OPENCONTAINER + flags = OPENCONTAINER -obj/item/weapon/reagent_containers/glass/solution_tray/attackby(obj/item/weapon/W as obj, mob/living/user as mob) +obj/item/weapon/reagent_containers/glass/solution_tray/attackby(obj/item/weapon/W as obj, mob/living/user as mob, params) if(istype(W, /obj/item/weapon/pen)) var/new_label = input("What should the new label be?","Label solution tray") if(new_label) diff --git a/code/modules/research/xenoarchaeology/finds/finds.dm b/code/modules/research/xenoarchaeology/finds/finds.dm index a8f5a8f6cb1..cfe6cc2c57c 100644 --- a/code/modules/research/xenoarchaeology/finds/finds.dm +++ b/code/modules/research/xenoarchaeology/finds/finds.dm @@ -45,7 +45,7 @@ if(severity && prob(30)) src.visible_message("The [src] crumbles away, leaving some dust and gravel behind.")*/ -/obj/item/weapon/ore/strangerock/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/ore/strangerock/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/weldingtool/)) var/obj/item/weapon/weldingtool/w = W if(w.isOn()) @@ -183,12 +183,12 @@ apply_image_decorations = 1 if(8) item_type = "handcuffs" - new_item = new /obj/item/weapon/handcuffs(src.loc) + new_item = new /obj/item/weapon/restraints/handcuffs(src.loc) additional_desc = "[pick("They appear to be for securing two things together","Looks kinky","Doesn't seem like a children's toy")]." if(9) item_type = "[pick("wicked","evil","byzantine","dangerous")] looking [pick("device","contraption","thing","trap")]" apply_prefix = 0 - new_item = new /obj/item/weapon/legcuffs/beartrap(src.loc) + new_item = new /obj/item/weapon/restraints/legcuffs/beartrap(src.loc) additional_desc = "[pick("It looks like it could take a limb off",\ "Could be some kind of animal trap",\ "There appear to be [pick("dark red","dark purple","dark green","dark blue")] stains along part of it")]." @@ -250,7 +250,7 @@ if(prob(75)) new_item = new /obj/item/weapon/pen(src.loc) else - new_item = new /obj/item/weapon/pen/sleepypen(src.loc) + new_item = new /obj/item/weapon/pen/sleepy(src.loc) if(prob(30)) apply_image_decorations = 1 if(16) @@ -347,7 +347,7 @@ if(spawn_type) var/obj/item/weapon/gun/energy/new_gun = new spawn_type(src.loc) new_item = new_gun - new_item.icon_state = "egun[rand(1,6)]" + new_item.icon_state = pick("laser","retro","laser","caplaser","xray","energy","laser") new_gun.desc = "This is an antique energy weapon, you're not sure if it will fire or not." //5% chance to explode when first fired @@ -544,12 +544,14 @@ if(talkative) new_item.talking_atom = new() - talking_atom.holder_atom = new_item - talking_atom.init() + if(talking_atom) + talking_atom.holder_atom = new_item + talking_atom.init() del(src) else if(talkative) src.talking_atom = new() - talking_atom.holder_atom = src - talking_atom.init() + if(talking_atom) + talking_atom.holder_atom = src + talking_atom.init() diff --git a/code/modules/research/xenoarchaeology/finds/finds_fossils.dm b/code/modules/research/xenoarchaeology/finds/finds_fossils.dm index 57d510015fc..8338de5a3ae 100644 --- a/code/modules/research/xenoarchaeology/finds/finds_fossils.dm +++ b/code/modules/research/xenoarchaeology/finds/finds_fossils.dm @@ -33,7 +33,7 @@ icon_state = "hskull" desc = "It's a fossilised, horned skull." -/obj/item/weapon/fossil/skull/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/fossil/skull/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/fossil/bone)) var/obj/o = new /obj/skeleton(get_turf(src)) var/a = new /obj/item/weapon/fossil/bone @@ -57,7 +57,7 @@ src.breq = rand(6)+3 src.desc = "An incomplete skeleton, looks like it could use [src.breq-src.bnum] more bones." -/obj/skeleton/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/skeleton/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/fossil/bone)) if(!bstate) bnum++ diff --git a/code/modules/research/xenoarchaeology/finds/finds_misc.dm b/code/modules/research/xenoarchaeology/finds/finds_misc.dm index c15d5f76f6b..06ac8960c44 100644 --- a/code/modules/research/xenoarchaeology/finds/finds_misc.dm +++ b/code/modules/research/xenoarchaeology/finds/finds_misc.dm @@ -24,7 +24,7 @@ else return -/obj/item/weapon/shard/plasma/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/weapon/shard/plasma/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if ( istype(W, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/WT = W @@ -35,7 +35,7 @@ continue if(G.amount>=G.max_amount) continue - G.attackby(NG, user) + G.attackby(NG, user, params) usr << "You add the newly-formed plasma glass to the stack. It now contains [NG.amount] sheets." //SN src = null returnToPool(src) diff --git a/code/modules/research/xenoarchaeology/genetics/reconstitutor.dm b/code/modules/research/xenoarchaeology/genetics/reconstitutor.dm index bd2780835e6..a100d159d4b 100644 --- a/code/modules/research/xenoarchaeology/genetics/reconstitutor.dm +++ b/code/modules/research/xenoarchaeology/genetics/reconstitutor.dm @@ -47,7 +47,7 @@ datum/genesequence undiscovered_genesequences = master_controller.all_animal_genesequences.Copy() ..() -/obj/machinery/computer/reconstitutor/attackby(obj/item/W, mob/user) +/obj/machinery/computer/reconstitutor/attackby(obj/item/W, mob/user, params) if(istype(W,/obj/item/weapon/fossil)) user.drop_item() W.loc = src.loc diff --git a/code/modules/research/xenoarchaeology/machinery/artifact_harvester.dm b/code/modules/research/xenoarchaeology/machinery/artifact_harvester.dm index 776d91751c2..9209e062657 100644 --- a/code/modules/research/xenoarchaeology/machinery/artifact_harvester.dm +++ b/code/modules/research/xenoarchaeology/machinery/artifact_harvester.dm @@ -21,7 +21,7 @@ if(!owned_scanner) owned_scanner = locate(/obj/machinery/artifact_scanpad) in orange(1, src) -/obj/machinery/artifact_harvester/attackby(var/obj/I as obj, var/mob/user as mob) +/obj/machinery/artifact_harvester/attackby(var/obj/I as obj, var/mob/user as mob, params) if(istype(I,/obj/item/weapon/anobattery)) if(!inserted_battery) user << "\blue You insert [I] into [src]." diff --git a/code/modules/research/xenoarchaeology/machinery/geosample_scanner.dm b/code/modules/research/xenoarchaeology/machinery/geosample_scanner.dm index 6a44fbe72d7..3e15764fee6 100644 --- a/code/modules/research/xenoarchaeology/machinery/geosample_scanner.dm +++ b/code/modules/research/xenoarchaeology/machinery/geosample_scanner.dm @@ -63,7 +63,7 @@ /obj/machinery/radiocarbon_spectrometer/attack_hand(var/mob/user as mob) ui_interact(user) -/obj/machinery/radiocarbon_spectrometer/attackby(var/obj/I as obj, var/mob/user as mob) +/obj/machinery/radiocarbon_spectrometer/attackby(var/obj/I as obj, var/mob/user as mob, params) if(scanning) user << "You can't do that while [src] is scanning!" else diff --git a/code/modules/research/xenoarchaeology/tools/ano_device_battery.dm b/code/modules/research/xenoarchaeology/tools/ano_device_battery.dm index fc50c956e74..ce5c546e9d5 100644 --- a/code/modules/research/xenoarchaeology/tools/ano_device_battery.dm +++ b/code/modules/research/xenoarchaeology/tools/ano_device_battery.dm @@ -37,7 +37,7 @@ ..() processing_objects.Add(src) -/obj/item/weapon/anodevice/attackby(var/obj/I as obj, var/mob/user as mob) +/obj/item/weapon/anodevice/attackby(var/obj/I as obj, var/mob/user as mob, params) if(istype(I, /obj/item/weapon/anobattery)) if(!inserted_battery) user << "\blue You insert the battery." diff --git a/code/modules/research/xenoarchaeology/tools/bunsen_burner.dm b/code/modules/research/xenoarchaeology/tools/bunsen_burner.dm index 2437eeb0672..a90105585ee 100644 --- a/code/modules/research/xenoarchaeology/tools/bunsen_burner.dm +++ b/code/modules/research/xenoarchaeology/tools/bunsen_burner.dm @@ -9,7 +9,7 @@ var/obj/item/weapon/reagent_containers/held_container var/heat_time = 50 -/obj/machinery/bunsen_burner/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/bunsen_burner/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/reagent_containers)) if(held_container) user << "\red You must remove the [held_container] first." diff --git a/code/modules/research/xenoarchaeology/tools/suspension_generator.dm b/code/modules/research/xenoarchaeology/tools/suspension_generator.dm index e0a1faf60d2..dd129d48d47 100644 --- a/code/modules/research/xenoarchaeology/tools/suspension_generator.dm +++ b/code/modules/research/xenoarchaeology/tools/suspension_generator.dm @@ -5,7 +5,7 @@ icon_state = "suspension2" density = 1 req_access = list(access_research) - var/obj/item/weapon/cell/cell + var/obj/item/weapon/stock_parts/cell/cell var/obj/item/weapon/card/id/auth_card var/locked = 1 var/open = 0 @@ -16,7 +16,7 @@ var/list/secured_mobs = list() /obj/machinery/suspension_gen/New() - src.cell = new/obj/item/weapon/cell/high(src) + src.cell = new/obj/item/weapon/stock_parts/cell/high(src) ..() /obj/machinery/suspension_gen/process() @@ -168,7 +168,7 @@ cell = null user << "You remove the power cell" -/obj/machinery/suspension_gen/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/suspension_gen/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/screwdriver)) if(!open) if(screwed) @@ -205,7 +205,7 @@ desc = "It has stubby legs bolted up against it's body for stabilising." else user << "You are unable to secure [src] while it is active!" - else if (istype(W, /obj/item/weapon/cell)) + else if (istype(W, /obj/item/weapon/stock_parts/cell)) if(open) if(cell) user << "There is a power cell already installed." diff --git a/code/modules/research/xenoarchaeology/tools/tools_anoscanner.dm b/code/modules/research/xenoarchaeology/tools/tools_anoscanner.dm index 7cfe69d1e35..8b1dc2f60ee 100644 --- a/code/modules/research/xenoarchaeology/tools/tools_anoscanner.dm +++ b/code/modules/research/xenoarchaeology/tools/tools_anoscanner.dm @@ -5,7 +5,6 @@ icon_state = "flashgun" item_state = "lampgreen" w_class = 1.0 - flags = FPRINT | TABLEPASS slot_flags = SLOT_BELT var/nearest_artifact_id = "unknown" var/nearest_artifact_distance = -1 diff --git a/code/modules/research/xenoarchaeology/tools/tools_coresampler.dm b/code/modules/research/xenoarchaeology/tools/tools_coresampler.dm index 344a6ccb225..1aa2a4a37eb 100644 --- a/code/modules/research/xenoarchaeology/tools/tools_coresampler.dm +++ b/code/modules/research/xenoarchaeology/tools/tools_coresampler.dm @@ -20,7 +20,6 @@ icon_state = "sampler0" item_state = "screwdriver_brown" w_class = 1.0 - flags = FPRINT | TABLEPASS //slot_flags = SLOT_BELT var/sampled_turf = "" var/num_stored_bags = 10 @@ -36,7 +35,7 @@ else return ..() -/obj/item/device/core_sampler/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/item/device/core_sampler/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W,/obj/item/weapon/evidencebag)) if(num_stored_bags < 10) del(W) diff --git a/code/modules/research/xenoarchaeology/tools/tools_depthscanner.dm b/code/modules/research/xenoarchaeology/tools/tools_depthscanner.dm index ad9a525b716..7c55b81004a 100644 --- a/code/modules/research/xenoarchaeology/tools/tools_depthscanner.dm +++ b/code/modules/research/xenoarchaeology/tools/tools_depthscanner.dm @@ -10,7 +10,6 @@ icon_state = "crap" item_state = "analyzer" w_class = 1.0 - flags = FPRINT | TABLEPASS slot_flags = SLOT_BELT var/list/positive_locations = list() var/datum/depth_scan/current diff --git a/code/modules/research/xenoarchaeology/tools/tools_pickaxe.dm b/code/modules/research/xenoarchaeology/tools/tools_pickaxe.dm index 62bd9009603..48a5e0514d4 100644 --- a/code/modules/research/xenoarchaeology/tools/tools_pickaxe.dm +++ b/code/modules/research/xenoarchaeology/tools/tools_pickaxe.dm @@ -10,7 +10,7 @@ digspeed = 20 desc = "Thick metallic wires for clearing away dust and loose scree (1 centimetre excavation depth)." excavation_amount = 0.5 - drill_sound = 'sound/weapons/thudswoosh.ogg' + digsound = list('sound/weapons/thudswoosh.ogg') drill_verb = "brushing" w_class = 2 @@ -22,7 +22,7 @@ digspeed = 20 desc = "A miniature excavation tool for precise digging (2 centimetre excavation depth)." excavation_amount = 1 - drill_sound = 'sound/items/Screwdriver.ogg' + digsound = list('sound/items/Screwdriver.ogg') drill_verb = "delicately picking" w_class = 2 @@ -34,7 +34,7 @@ digspeed = 20 desc = "A miniature excavation tool for precise digging (4 centimetre excavation depth)." excavation_amount = 2 - drill_sound = 'sound/items/Screwdriver.ogg' + digsound = list('sound/items/Screwdriver.ogg') drill_verb = "delicately picking" w_class = 2 @@ -46,7 +46,7 @@ digspeed = 20 desc = "A miniature excavation tool for precise digging (6 centimetre excavation depth)." excavation_amount = 3 - drill_sound = 'sound/items/Screwdriver.ogg' + digsound = list('sound/items/Screwdriver.ogg') drill_verb = "delicately picking" w_class = 2 @@ -58,7 +58,7 @@ digspeed = 20 desc = "A miniature excavation tool for precise digging (8 centimetre excavation depth)." excavation_amount = 4 - drill_sound = 'sound/items/Screwdriver.ogg' + digsound = list('sound/items/Screwdriver.ogg') drill_verb = "delicately picking" w_class = 2 @@ -70,7 +70,7 @@ digspeed = 20 desc = "A miniature excavation tool for precise digging (10 centimetre excavation depth)." excavation_amount = 5 - drill_sound = 'sound/items/Screwdriver.ogg' + digsound = list('sound/items/Screwdriver.ogg') drill_verb = "delicately picking" w_class = 2 @@ -82,7 +82,7 @@ digspeed = 20 desc = "A miniature excavation tool for precise digging (12 centimetre excavation depth)." excavation_amount = 6 - drill_sound = 'sound/items/Screwdriver.ogg' + digsound = list('sound/items/Screwdriver.ogg') drill_verb = "delicately picking" w_class = 2 @@ -94,7 +94,7 @@ digspeed = 30 desc = "A smaller, more precise version of the pickaxe (30 centimetre excavation depth)." excavation_amount = 15 - drill_sound = 'sound/items/Crowbar.ogg' + digsound = list('sound/items/Crowbar.ogg') drill_verb = "clearing" w_class = 3 diff --git a/code/modules/security levels/keycard authentication.dm b/code/modules/security levels/keycard authentication.dm index 9d94725adf6..361c384a915 100644 --- a/code/modules/security levels/keycard authentication.dm +++ b/code/modules/security levels/keycard authentication.dm @@ -28,7 +28,7 @@ user << "You are too primitive to use this device." return -/obj/machinery/keycard_auth/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/keycard_auth/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(stat & (NOPOWER|BROKEN)) user << "This device is not powered." return diff --git a/code/modules/security levels/security levels.dm b/code/modules/security levels/security levels.dm index b85d9589209..5ac35d1188e 100644 --- a/code/modules/security levels/security levels.dm +++ b/code/modules/security levels/security levels.dm @@ -7,6 +7,8 @@ //5 = code delta //config.alert_desc_blue_downto +/var/datum/announcement/priority/security/security_announcement_up = new(do_log = 0, do_newscast = 1, new_sound = sound('sound/misc/notice1.ogg')) +/var/datum/announcement/priority/security/security_announcement_down = new(do_log = 0, do_newscast = 1) /proc/set_security_level(var/level) switch(level) @@ -27,40 +29,35 @@ if(level >= SEC_LEVEL_GREEN && level <= SEC_LEVEL_DELTA && level != security_level) switch(level) if(SEC_LEVEL_GREEN) - world << "Attention! Security level lowered to green." - world << "All threats to the station have passed. All weapons need to be holstered and privacy laws are once again fully enforced." + security_announcement_down.Announce("All threats to the station have passed. All weapons need to be holstered and privacy laws are once again fully enforced.","Attention! Security level lowered to green.") security_level = SEC_LEVEL_GREEN for(var/obj/machinery/firealarm/FA in world) - if(FA.z == 1 || FA.z == 5) + if((FA.z in config.contact_levels)) FA.overlays = list() FA.overlays += image('icons/obj/monitors.dmi', "overlay_green") if(SEC_LEVEL_BLUE) if(security_level < SEC_LEVEL_BLUE) - world << "Attention! Security level elevated to blue." - world << "The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible and random searches are permitted." + security_announcement_up.Announce("The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible and random searches are permitted.","Attention! Security level elevated to blue.") else - world << "Attention! Security level lowered to blue." - world << "The immediate threat has passed. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still allowed." + security_announcement_down.Announce("The immediate threat has passed. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still allowed.","Attention! Security level lowered to blue.") security_level = SEC_LEVEL_BLUE for(var/obj/machinery/firealarm/FA in world) - if(FA.z == 1 || FA.z == 5) + if((FA.z in config.contact_levels)) FA.overlays = list() FA.overlays += image('icons/obj/monitors.dmi', "overlay_blue") if(SEC_LEVEL_RED) if(security_level < SEC_LEVEL_RED) - world << "Attention! Code Red!" - world << "There is an immediate and serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised. The station's secure armory has been unlocked and is ready for use." + security_announcement_up.Announce("There is an immediate and serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised.","Attention! Code Red!") else - world << "Attention! Code Red!" - world << "The station's self-destruct mechanism has been deactivated, but there is still an immediate and serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised." + security_announcement_down.Announce("The station's self-destruct mechanism has been deactivated, but there is still an immediate and serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised.","Attention! Code Red!") security_level = SEC_LEVEL_RED var/obj/machinery/door/airlock/highsecurity/red/R = locate(/obj/machinery/door/airlock/highsecurity/red) in world - if(R && R.z == 1) + if(R && (R.z in config.station_levels)) R.locked = 0 R.update_icon() @@ -69,25 +66,24 @@ CC.post_status("alert", "redalert") for(var/obj/machinery/firealarm/FA in world) - if(FA.z == 1 || FA.z == 5) + if((FA.z in config.contact_levels)) FA.overlays = list() FA.overlays += image('icons/obj/monitors.dmi', "overlay_red") if(SEC_LEVEL_GAMMA) - world << "Attention! Gamma security level activated!" - world << "Central Command has ordered the Gamma security level on the station. Security is to have weapons equipped at all times, and all civilians are to immediately seek their nearest head for transportation to a secure location. The station's Gamma armory has been unlocked and is ready for use." + security_announcement_up.Announce("Central Command has ordered the Gamma security level on the station. Security is to have weapons equipped at all times, and all civilians are to immediately seek their nearest head for transportation to a secure location. The station's Gamma armory has been unlocked and is ready for use.","Attention! Gamma security level activated!") security_level = SEC_LEVEL_GAMMA move_gamma_ship() if(security_level < SEC_LEVEL_RED) for(var/obj/machinery/door/airlock/highsecurity/red/R in world) - if(R.z == 1) + if((R.z in config.station_levels)) R.locked = 0 R.update_icon() for(var/obj/machinery/door/airlock/hatch/gamma/H in world) - if(H.z == 1) + if((H.z in config.station_levels)) H.locked = 0 H.update_icon() @@ -96,14 +92,13 @@ CC.post_status("alert", "redalert") for(var/obj/machinery/firealarm/FA in world) - if(FA.z == 1 || FA.z == 5) + if((FA.z in config.contact_levels)) FA.overlays = list() FA.overlays += image('icons/obj/monitors.dmi', "overlay_gamma") FA.update_icon() if(SEC_LEVEL_EPSILON) - world << "Attention! Epsilon security level activated!" - world << "Central Command has ordered the Epsilon security level on the station. Consider all contracts terminated." + security_announcement_up.Announce("Central Command has ordered the Epsilon security level on the station. Consider all contracts terminated.","Attention! Epsilon security level activated!") security_level = SEC_LEVEL_EPSILON var/obj/machinery/computer/communications/CC = locate(/obj/machinery/computer/communications,world) @@ -111,13 +106,12 @@ CC.post_status("alert", "redalert") for(var/obj/machinery/firealarm/FA in world) - if(FA.z == 1 || FA.z == 5) + if((FA.z in config.contact_levels)) FA.overlays = list() FA.overlays += image('icons/obj/monitors.dmi', "overlay_epsilon") if(SEC_LEVEL_DELTA) - world << "Attention! Delta security level reached!" - world << "The station's self-destruct mechanism has been engaged. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill." + security_announcement_up.Announce("The station's self-destruct mechanism has been engaged. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill.","Attention! Delta security level reached!") security_level = SEC_LEVEL_DELTA var/obj/machinery/computer/communications/CC = locate(/obj/machinery/computer/communications,world) @@ -125,7 +119,7 @@ CC.post_status("alert", "redalert") for(var/obj/machinery/firealarm/FA in world) - if(FA.z == 1 || FA.z == 5) + if((FA.z in config.contact_levels)) FA.overlays = list() FA.overlays += image('icons/obj/monitors.dmi', "overlay_delta") diff --git a/code/modules/shieldgen/shield_capacitor.dm b/code/modules/shieldgen/shield_capacitor.dm index cd424dbe120..192449d7735 100644 --- a/code/modules/shieldgen/shield_capacitor.dm +++ b/code/modules/shieldgen/shield_capacitor.dm @@ -32,7 +32,7 @@ break ..() -/obj/machinery/shield_capacitor/attackby(obj/item/W, mob/user) +/obj/machinery/shield_capacitor/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/weapon/card/id)) var/obj/item/weapon/card/id/C = W diff --git a/code/modules/shieldgen/shield_gen.dm b/code/modules/shieldgen/shield_gen.dm index 88d4b46b89f..97375aa9c26 100644 --- a/code/modules/shieldgen/shield_gen.dm +++ b/code/modules/shieldgen/shield_gen.dm @@ -41,7 +41,7 @@ field = new/list() ..() -/obj/machinery/shield_gen/attackby(obj/item/W, mob/user) +/obj/machinery/shield_gen/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/weapon/card/id)) var/obj/item/weapon/card/id/C = W if(access_captain in C.access || access_security in C.access || access_engine in C.access) diff --git a/code/modules/shuttles/escape_pods.dm b/code/modules/shuttles/escape_pods.dm index 0261997a9d3..17a97b79fe7 100644 --- a/code/modules/shuttles/escape_pods.dm +++ b/code/modules/shuttles/escape_pods.dm @@ -89,19 +89,14 @@ ui.open() ui.set_auto_update(1) -/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/card/emag) && !emagged) +/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth/emag_act(user as mob) + if (!emagged) user << "\blue You emag the [src], arming the escape pod!" emagged = 1 if (istype(docking_program, /datum/computer/file/embedded_program/docking/simple/escape_pod)) var/datum/computer/file/embedded_program/docking/simple/escape_pod/P = docking_program if (!P.armed) P.arm() - return - - ..() - - //A docking controller program for a simple door based docking port /datum/computer/file/embedded_program/docking/simple/escape_pod diff --git a/code/modules/shuttles/shuttle_console.dm b/code/modules/shuttles/shuttle_console.dm index f1ca624e73b..e6e7a8d4112 100644 --- a/code/modules/shuttles/shuttle_console.dm +++ b/code/modules/shuttles/shuttle_console.dm @@ -97,15 +97,11 @@ return shuttle.cancel_launch(user) -/obj/machinery/computer/shuttle_control/attackby(obj/item/weapon/W as obj, mob/user as mob) - - if (istype(W, /obj/item/weapon/card/emag)) - src.req_access = list() - src.req_one_access = list() - hacked = 1 - usr << "You short out the console's ID checking system. It's now available to everyone!" - else - ..() +/obj/machinery/computer/shuttle_control/emag_act(user as mob) + src.req_access = list() + src.req_one_access = list() + hacked = 1 + usr << "You short out the console's ID checking system. It's now available to everyone!" /obj/machinery/computer/shuttle_control/bullet_act(var/obj/item/projectile/Proj) visible_message("[Proj] ricochets off [src]!") diff --git a/code/modules/shuttles/shuttle_emergency.dm b/code/modules/shuttles/shuttle_emergency.dm index b5268fd2ca5..4350591c548 100644 --- a/code/modules/shuttles/shuttle_emergency.dm +++ b/code/modules/shuttles/shuttle_emergency.dm @@ -6,7 +6,7 @@ if (istype(in_use, /obj/machinery/computer/shuttle_control/emergency)) var/obj/machinery/computer/shuttle_control/emergency/C = in_use C.reset_authorization() - + emergency_shuttle.shuttle_arrived() /datum/shuttle/ferry/emergency/long_jump(var/area/departing, var/area/destination, var/area/interim, var/travel_time, var/direction) @@ -26,9 +26,9 @@ emergency_shuttle.departed = 1 if (emergency_shuttle.evac) - captain_announce("The Emergency Shuttle has left the station. Estimate [round(emergency_shuttle.estimate_arrival_time()/60,1)] minutes until the shuttle docks at Central Command.") + priority_announcement.Announce("The Emergency Shuttle has left the station. Estimate [round(emergency_shuttle.estimate_arrival_time()/60,1)] minutes until the shuttle docks at Central Command.") else - captain_announce("The Crew Transfer Shuttle has left the station. Estimate [round(emergency_shuttle.estimate_arrival_time()/60,1)] minutes until the shuttle docks at Central Command.") + priority_announcement.Announce("The Crew Transfer Shuttle has left the station. Estimate [round(emergency_shuttle.estimate_arrival_time()/60,1)] minutes until the shuttle docks at Central Command.") ..(origin, destination) @@ -37,7 +37,7 @@ var/obj/machinery/computer/shuttle_control/emergency/C = user if (!C.has_authorization()) return 0 - + if(moving_status == SHUTTLE_STRANDED && C.has_authorization()) return 1 return ..() @@ -45,12 +45,12 @@ /datum/shuttle/ferry/emergency/can_force(var/mob/user) if (istype(user, /obj/machinery/computer/shuttle_control/emergency)) var/obj/machinery/computer/shuttle_control/emergency/C = user - + //initiating or cancelling a launch ALWAYS requires authorization, but if we are already set to launch anyways than forcing does not. //this is so that people can force launch if the docking controller cannot safely undock without needing X heads to swipe. if (process_state != WAIT_LAUNCH && !C.has_authorization()) return 0 - + return ..() /datum/shuttle/ferry/emergency/can_cancel(var/mob/user) @@ -62,7 +62,7 @@ /datum/shuttle/ferry/emergency/launch(var/user) if (!can_launch(user)) return - + if(emergency_shuttle.no_escape) user << "The emergency shuttle has been disabled by Centcom." return @@ -152,15 +152,16 @@ -/obj/machinery/computer/shuttle_control/emergency/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/card/emag) && !emagged) +/obj/machinery/computer/shuttle_control/emergency/attackby(obj/item/weapon/W as obj, mob/user as mob, params) + read_authorization(W) + ..() + +/obj/machinery/computer/shuttle_control/emergency/emag_act(user as mob) + if (!emagged) user << "\blue You short out the [src]'s authorization protocols." emagged = 1 return - read_authorization(W) - ..() - /obj/machinery/computer/shuttle_control/emergency/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) var/data[0] var/datum/shuttle/ferry/emergency/shuttle = shuttle_controller.shuttles[shuttle_tag] @@ -213,7 +214,7 @@ "docking_status" = shuttle.docking_controller? shuttle.docking_controller.get_docking_status() : null, "docking_override" = shuttle.docking_controller? shuttle.docking_controller.override_enabled : null, "can_launch" = shuttle.can_launch(src), - "can_cancel" = shuttle.can_cancel(src), + //"can_cancel" = shuttle.can_cancel(src), "can_force" = shuttle.can_force(src), "auth_list" = auth_list, "has_auth" = has_auth, @@ -235,7 +236,7 @@ if(href_list["removeid"]) var/dna_hash = href_list["removeid"] authorized -= dna_hash - + if(!emagged && href_list["scanid"]) //They selected an empty entry. Try to scan their id. if (ishuman(usr)) diff --git a/code/modules/shuttles/shuttles_multi.dm b/code/modules/shuttles/shuttles_multi.dm index 3a73cafb58f..bac0384a4d3 100644 --- a/code/modules/shuttles/shuttles_multi.dm +++ b/code/modules/shuttles/shuttles_multi.dm @@ -33,14 +33,14 @@ if(cloaked || isnull(departure_message)) return - command_alert(departure_message,(announcer ? announcer : "Central Command")) + command_announcement.Announce(departure_message,(announcer ? announcer : "Central Command")) /datum/shuttle/multi_shuttle/proc/announce_arrival() if(cloaked || isnull(arrival_message)) return - command_alert(arrival_message,(announcer ? announcer : "Central Command")) + command_announcement.Announce(arrival_message,(announcer ? announcer : "Central Command")) /obj/machinery/computer/shuttle_control/multi icon_state = "syndishuttle" diff --git a/code/modules/store/store.dm b/code/modules/store/store.dm index 02a50c1b31a..41df9937fab 100644 --- a/code/modules/store/store.dm +++ b/code/modules/store/store.dm @@ -48,7 +48,7 @@ var/global/datum/store/centcomm_store=new /datum/store/proc/reconnect_database() for(var/obj/machinery/account_database/DB in world) - if(DB.z == 1) + if((DB.z in config.station_levels)) linked_db = DB break diff --git a/code/modules/supermatter/supermatter.dm b/code/modules/supermatter/supermatter.dm index f2e05b18256..27f4fc41602 100644 --- a/code/modules/supermatter/supermatter.dm +++ b/code/modules/supermatter/supermatter.dm @@ -278,12 +278,12 @@ R.receive_pulse(power * POWER_FACTOR) return -/obj/machinery/power/supermatter/attackby(obj/item/weapon/W as obj, mob/living/user as mob) +/obj/machinery/power/supermatter/attackby(obj/item/weapon/W as obj, mob/living/user as mob, params) user.visible_message("\The [user] touches \a [W] to \the [src] as a silence fills the room...",\ "You touch \the [W] to \the [src] when everything suddenly goes silent.\"\n\The [W] flashes into dust as you flinch away from \the [src].",\ "Everything suddenly goes silent.") - user.drop_from_inventory(W) + user.unEquip(W) Consume(W) user.apply_effect(150, IRRADIATE) diff --git a/code/modules/surgery/braincore.dm b/code/modules/surgery/braincore.dm index 3ce95d81553..92e2124b619 100644 --- a/code/modules/surgery/braincore.dm +++ b/code/modules/surgery/braincore.dm @@ -12,7 +12,8 @@ /datum/surgery_step/brain/saw_skull allowed_tools = list( /obj/item/weapon/circular_saw = 100, \ - /obj/item/weapon/hatchet = 75 + /obj/item/weapon/hatchet = 75, \ + /obj/item/weapon/melee/arm_blade = 60 // Dr. Chang E. Ling, MD ) min_duration = 50 @@ -67,7 +68,8 @@ /datum/surgery_step/brain/saw_spine allowed_tools = list( /obj/item/weapon/circular_saw = 100, \ - /obj/item/weapon/hatchet = 75 + /obj/item/weapon/hatchet = 75, \ + /obj/item/weapon/melee/arm_blade = 60 ) min_duration = 50 diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm index 17b926ae99a..37e465946bd 100644 --- a/code/modules/surgery/generic.dm +++ b/code/modules/surgery/generic.dm @@ -187,7 +187,8 @@ /datum/surgery_step/generic/cut_limb allowed_tools = list( /obj/item/weapon/circular_saw = 100, \ - /obj/item/weapon/hatchet = 75 + /obj/item/weapon/hatchet = 75, \ + /obj/item/weapon/melee/arm_blade = 60 ) min_duration = 110 diff --git a/code/modules/surgery/headreattach.dm b/code/modules/surgery/headreattach.dm index 3c49a9e8c0a..c493607c52c 100644 --- a/code/modules/surgery/headreattach.dm +++ b/code/modules/surgery/headreattach.dm @@ -196,7 +196,7 @@ user.visible_message("\blue [user] has attached [target]'s head to the body.", \ "\blue You have attached [target]'s head to the body.") affected.status = 0 - if(istype(target,/mob/living/carbon/human/machine)) + if(target.species && (target.species.flags & IS_SYNTHETIC)) affected.status = 128 affected.amputated = 0 affected.destspawn = 0 diff --git a/code/modules/surgery/ribcage.dm b/code/modules/surgery/ribcage.dm index cce3a13375b..e9707c1a181 100644 --- a/code/modules/surgery/ribcage.dm +++ b/code/modules/surgery/ribcage.dm @@ -12,7 +12,8 @@ /datum/surgery_step/ribcage/saw_ribcage allowed_tools = list( /obj/item/weapon/circular_saw = 100, \ - /obj/item/weapon/hatchet = 75 + /obj/item/weapon/hatchet = 75, \ + /obj/item/weapon/melee/arm_blade = 60 ) min_duration = 50 @@ -146,7 +147,7 @@ user.visible_message(msg, self_msg) target.op_stage.ribcage = 0 - + ////////////////////////////////////////////////////////////////// // ALIEN EMBRYO SURGERY // ////////////////////////////////////////////////////////////////// diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index 07d5f7df40a..991e1714587 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -90,7 +90,8 @@ proc/do_surgery(mob/living/M, mob/living/user, obj/item/tool) if( prob(S.tool_quality(tool)) && do_mob(user, M, rand(S.min_duration, S.max_duration))) S.end_step(user, M, user.zone_sel.selecting, tool) //finish successfully else //or - S.fail_step(user, M, user.zone_sel.selecting, tool) //malpractice~ + if(!isrobot(user)) + S.fail_step(user, M, user.zone_sel.selecting, tool) //malpractice~ return 1 //don't want to do weapony things after surgery return 0 diff --git a/code/modules/telesci/gps.dm b/code/modules/telesci/gps.dm index 25c5bb154e6..c0a3e9fd58f 100644 --- a/code/modules/telesci/gps.dm +++ b/code/modules/telesci/gps.dm @@ -61,7 +61,7 @@ var/list/GPS_list = list() ..() if(href_list["tag"] ) var/a = input("Please enter desired tag.", name, gpstag) as text - a = uppertext(copytext(sanitize(a), 1, 5)) + a = uppertext(sanitize(copytext(a, 1, 5))) if(src.loc == usr) gpstag = a name = "global positioning system ([gpstag])" diff --git a/code/modules/telesci/telepad.dm b/code/modules/telesci/telepad.dm index 21283526863..9aefbc23297 100644 --- a/code/modules/telesci/telepad.dm +++ b/code/modules/telesci/telepad.dm @@ -27,7 +27,7 @@ E += C.rating efficiency = E -/obj/machinery/telepad/attackby(obj/item/I, mob/user) +/obj/machinery/telepad/attackby(obj/item/I, mob/user, params) if(default_deconstruction_screwdriver(user, "pad-idle-o", "pad-idle", I)) return @@ -54,7 +54,7 @@ idle_power_usage = 20 active_power_usage = 500 var/stage = 0 -/obj/machinery/telepad_cargo/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/machinery/telepad_cargo/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/wrench)) playsound(src, 'sound/items/Ratchet.ogg', 50, 1) if(anchored) @@ -147,11 +147,12 @@ playsound(src.loc, 'sound/effects/pop.ogg', 50, 0) user << " You calibrate the telepad locator." -/obj/item/weapon/rcs/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/weapon/card/emag) && emagged == 0) +/obj/item/weapon/rcs/emag_act(user as mob) + if(!emagged) emagged = 1 var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(5, 1, src) s.start() user << " You emag the RCS. Click on it to toggle between modes." - return \ No newline at end of file + return + \ No newline at end of file diff --git a/code/modules/telesci/telesci_computer.dm b/code/modules/telesci/telesci_computer.dm index f37ec393860..6d53a63aa10 100644 --- a/code/modules/telesci/telesci_computer.dm +++ b/code/modules/telesci/telesci_computer.dm @@ -54,13 +54,7 @@ user << "You are too primitive to use this computer." return -/obj/machinery/computer/telescience/attackby(obj/item/W, mob/user) - if(istype(W,/obj/item/weapon/card/emag)) - if (emagged == 0) - user << "\blue You scramble the Telescience authentication key to an unknown signal. You should be able to teleport to more places now!" - emagged = 1 - else - user << "\red The machine seems unaffected by the card swipe..." +/obj/machinery/computer/telescience/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/bluespace_crystal)) if(crystals.len >= max_crystals) user << "There are not enough crystal slots." @@ -73,7 +67,7 @@ else if(istype(W, /obj/item/device/gps)) if(!inserted_gps) inserted_gps = W - user.before_take_item(W) + user.unEquip(W) W.loc = src user.visible_message("[user] inserts [W] into \the [src]'s GPS device slot.") updateUsrDialog() @@ -86,6 +80,13 @@ updateUsrDialog() else ..() + +/obj/machinery/computer/telescience/emag_act(user as mob) + if (!emagged) + user << "\blue You scramble the Telescience authentication key to an unknown signal. You should be able to teleport to more places now!" + emagged = 1 + else + user << "\red The machine seems unaffected by the card swipe..." /obj/machinery/computer/telescience/attack_ai(mob/user) src.attack_hand(user) diff --git a/code/modules/vehicles/ambulance.dm b/code/modules/vehicles/ambulance.dm index 581b8ca8efd..a844526186d 100644 --- a/code/modules/vehicles/ambulance.dm +++ b/code/modules/vehicles/ambulance.dm @@ -39,7 +39,7 @@ //------------------------------------------- /obj/vehicle/train/ambulance/engine/New() ..() - cell = new /obj/item/weapon/cell/high + cell = new /obj/item/weapon/stock_parts/cell/high verbs -= /atom/movable/verb/pull key = new() @@ -58,14 +58,14 @@ return ..() -/obj/vehicle/train/ambulance/trolley/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/vehicle/train/ambulance/trolley/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(open && istype(W, /obj/item/weapon/wirecutters)) passenger_allowed = !passenger_allowed user.visible_message("[user] [passenger_allowed ? "cuts" : "mends"] a cable in [src].","You [passenger_allowed ? "cut" : "mend"] the load limiter cable.") else ..() -/obj/vehicle/train/ambulance/engine/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/vehicle/train/ambulance/engine/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/key/ambulance_train)) if(!key) user.drop_item() @@ -86,10 +86,10 @@ ..() flick("mulebot-emagged", src) -/obj/vehicle/train/ambulance/trolley/insert_cell(var/obj/item/weapon/cell/C, var/mob/living/carbon/human/H) +/obj/vehicle/train/ambulance/trolley/insert_cell(var/obj/item/weapon/stock_parts/cell/C, var/mob/living/carbon/human/H) return -/obj/vehicle/train/ambulance/engine/insert_cell(var/obj/item/weapon/cell/C, var/mob/living/carbon/human/H) +/obj/vehicle/train/ambulance/engine/insert_cell(var/obj/item/weapon/stock_parts/cell/C, var/mob/living/carbon/human/H) ..() update_stats() diff --git a/code/modules/vehicles/cargo_train.dm b/code/modules/vehicles/cargo_train.dm index cc416aa34b3..5d792c54d1b 100644 --- a/code/modules/vehicles/cargo_train.dm +++ b/code/modules/vehicles/cargo_train.dm @@ -40,7 +40,7 @@ //------------------------------------------- /obj/vehicle/train/cargo/engine/New() ..() - cell = new /obj/item/weapon/cell/high + cell = new /obj/item/weapon/stock_parts/cell/high verbs -= /atom/movable/verb/pull key = new() var/image/I = new(icon = 'icons/obj/vehicles.dmi', icon_state = "cargo_engine_overlay", layer = src.layer + 0.2) //over mobs @@ -59,14 +59,14 @@ return ..() -/obj/vehicle/train/cargo/trolley/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/vehicle/train/cargo/trolley/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(open && istype(W, /obj/item/weapon/wirecutters)) passenger_allowed = !passenger_allowed user.visible_message("[user] [passenger_allowed ? "cuts" : "mends"] a cable in [src].","You [passenger_allowed ? "cut" : "mend"] the load limiter cable.") else ..() -/obj/vehicle/train/cargo/engine/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/vehicle/train/cargo/engine/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/key/cargo_train)) if(!key) user.drop_item() @@ -82,10 +82,10 @@ else icon_state = initial(icon_state) -/obj/vehicle/train/cargo/trolley/insert_cell(var/obj/item/weapon/cell/C, var/mob/living/carbon/human/H) +/obj/vehicle/train/cargo/trolley/insert_cell(var/obj/item/weapon/stock_parts/cell/C, var/mob/living/carbon/human/H) return -/obj/vehicle/train/cargo/engine/insert_cell(var/obj/item/weapon/cell/C, var/mob/living/carbon/human/H) +/obj/vehicle/train/cargo/engine/insert_cell(var/obj/item/weapon/stock_parts/cell/C, var/mob/living/carbon/human/H) ..() update_stats() diff --git a/code/modules/vehicles/janicart.dm b/code/modules/vehicles/janicart.dm index 8219335c24a..0804d8ccb32 100644 --- a/code/modules/vehicles/janicart.dm +++ b/code/modules/vehicles/janicart.dm @@ -43,7 +43,7 @@ //------------------------------------------- /obj/vehicle/train/janitor/engine/New() ..() - cell = new /obj/item/weapon/cell/high + cell = new /obj/item/weapon/stock_parts/cell/high verbs -= /atom/movable/verb/pull key = new() var/datum/reagents/R = new/datum/reagents(100) @@ -65,7 +65,7 @@ return ..() -/obj/vehicle/train/janitor/trolley/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/vehicle/train/janitor/trolley/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(openTop) W.loc = src user.visible_message("[user] puts [W] in [src].","You put [W] in [src].") @@ -93,7 +93,7 @@ else icon_state = "trashcart" -/obj/vehicle/train/janitor/engine/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/vehicle/train/janitor/engine/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/key/janitor_train)) if(!key) user.drop_item() @@ -136,10 +136,10 @@ ..() flick("mulebot-emagged", src) -/obj/vehicle/train/janitor/trolley/insert_cell(var/obj/item/weapon/cell/C, var/mob/living/carbon/human/H) +/obj/vehicle/train/janitor/trolley/insert_cell(var/obj/item/weapon/stock_parts/cell/C, var/mob/living/carbon/human/H) return -/obj/vehicle/train/janitor/engine/insert_cell(var/obj/item/weapon/cell/C, var/mob/living/carbon/human/H) +/obj/vehicle/train/janitor/engine/insert_cell(var/obj/item/weapon/stock_parts/cell/C, var/mob/living/carbon/human/H) ..() update_stats() diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm index 1eaf42f62ce..bb78c9e9cd8 100644 --- a/code/modules/vehicles/vehicle.dm +++ b/code/modules/vehicles/vehicle.dm @@ -21,7 +21,7 @@ var/move_delay = 1 //set this to limit the speed of the vehicle var/movable = 1 - var/obj/item/weapon/cell/cell + var/obj/item/weapon/stock_parts/cell/cell var/charge_use = 5 //set this to adjust the amount of power the vehicle uses per move var/atom/movable/load //all vehicles can take a load, since they should all be a least drivable @@ -61,7 +61,7 @@ else return 0 -/obj/vehicle/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/vehicle/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/hand_labeler)) return if(istype(W, /obj/item/weapon/screwdriver)) @@ -72,7 +72,7 @@ else if(istype(W, /obj/item/weapon/crowbar) && cell && open) remove_cell(user) - else if(istype(W, /obj/item/weapon/cell) && !cell && open) + else if(istype(W, /obj/item/weapon/stock_parts/cell) && !cell && open) insert_cell(W, user) else if(istype(W, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/T = W @@ -87,8 +87,6 @@ user << "[src] does not need a repair." else user << "Unable to repair while [src] is off." - else if(istype(W, /obj/item/weapon/card/emag) && !emagged) - Emag(user) else if(hasvar(W,"force") && hasvar(W,"damtype")) switch(W.damtype) if("fire") @@ -99,6 +97,10 @@ healthcheck() else ..() + +/obj/vehicle/emag_act(user as mob) + if(!emagged) + Emag(user) /obj/vehicle/attack_animal(var/mob/living/simple_animal/M as mob) if(M.melee_damage_upper == 0) return @@ -236,13 +238,13 @@ turn_on() return -/obj/vehicle/proc/insert_cell(var/obj/item/weapon/cell/C, var/mob/living/carbon/human/H) +/obj/vehicle/proc/insert_cell(var/obj/item/weapon/stock_parts/cell/C, var/mob/living/carbon/human/H) if(cell) return if(!istype(C)) return - H.drop_from_inventory(C) + H.unEquip(C) C.forceMove(src) cell = C powercheck() diff --git a/code/modules/virus2/analyser.dm b/code/modules/virus2/analyser.dm index 8046c48af01..e68889837c4 100644 --- a/code/modules/virus2/analyser.dm +++ b/code/modules/virus2/analyser.dm @@ -10,7 +10,7 @@ var/obj/item/weapon/virusdish/dish = null -/obj/machinery/disease2/diseaseanalyser/attackby(var/obj/O as obj, var/mob/user as mob) +/obj/machinery/disease2/diseaseanalyser/attackby(var/obj/O as obj, var/mob/user as mob, params) if(!istype(O,/obj/item/weapon/virusdish)) return if(dish) diff --git a/code/modules/virus2/biohazard destroyer.dm b/code/modules/virus2/biohazard destroyer.dm index abd1803de86..1c5799d07a2 100644 --- a/code/modules/virus2/biohazard destroyer.dm +++ b/code/modules/virus2/biohazard destroyer.dm @@ -6,7 +6,7 @@ density = 1 anchored = 1 -/obj/machinery/disease2/biodestroyer/attackby(var/obj/I as obj, var/mob/user as mob) +/obj/machinery/disease2/biodestroyer/attackby(var/obj/I as obj, var/mob/user as mob, params) for(var/path in accepts) if(I.type in typesof(path)) user.drop_item() diff --git a/code/modules/virus2/centrifuge.dm b/code/modules/virus2/centrifuge.dm index b36e63ff3a0..9573e08ea50 100644 --- a/code/modules/virus2/centrifuge.dm +++ b/code/modules/virus2/centrifuge.dm @@ -9,7 +9,7 @@ var/obj/item/weapon/reagent_containers/glass/beaker/vial/sample = null var/datum/disease2/disease/virus2 = null -/obj/machinery/computer/centrifuge/attackby(var/obj/O as obj, var/mob/user as mob) +/obj/machinery/computer/centrifuge/attackby(var/obj/O as obj, var/mob/user as mob, params) if(istype(O, /obj/item/weapon/screwdriver)) return ..(O,user) diff --git a/code/modules/virus2/curer.dm b/code/modules/virus2/curer.dm index 44a0fd348b9..df27fdfb841 100644 --- a/code/modules/virus2/curer.dm +++ b/code/modules/virus2/curer.dm @@ -8,7 +8,7 @@ var/obj/item/weapon/reagent_containers/container = null -/obj/machinery/computer/curer/attackby(var/obj/I as obj, var/mob/user as mob) +/obj/machinery/computer/curer/attackby(var/obj/I as obj, var/mob/user as mob, params) if(istype(I,/obj/item/weapon/reagent_containers)) var/mob/living/carbon/C = user if(!container) @@ -32,7 +32,7 @@ state("The [src.name] Buzzes", "blue") return ..() - return + return /obj/machinery/computer/curer/attack_ai(var/mob/user as mob) return src.attack_hand(user) diff --git a/code/modules/virus2/diseasesplicer.dm b/code/modules/virus2/diseasesplicer.dm index 47a4402ab44..d1938d6cdb1 100644 --- a/code/modules/virus2/diseasesplicer.dm +++ b/code/modules/virus2/diseasesplicer.dm @@ -11,7 +11,7 @@ var/splicing = 0 var/scanning = 0 -/obj/machinery/computer/diseasesplicer/attackby(var/obj/I as obj, var/mob/user as mob) +/obj/machinery/computer/diseasesplicer/attackby(var/obj/I as obj, var/mob/user as mob, params) if(istype(I, /obj/item/weapon/screwdriver)) return ..(I,user) diff --git a/code/modules/virus2/dishincubator.dm b/code/modules/virus2/dishincubator.dm index f6c95be8b2d..cc79387c7e6 100644 --- a/code/modules/virus2/dishincubator.dm +++ b/code/modules/virus2/dishincubator.dm @@ -14,7 +14,7 @@ var/foodsupply = 0 var/toxins = 0 -/obj/machinery/disease2/incubator/attackby(var/obj/O as obj, var/mob/user as mob) +/obj/machinery/disease2/incubator/attackby(var/obj/O as obj, var/mob/user as mob, params) if(istype(O, /obj/item/weapon/reagent_containers/glass) || istype(O,/obj/item/weapon/reagent_containers/syringe)) if(beaker) diff --git a/code/modules/virus2/effect.dm b/code/modules/virus2/effect.dm index 6669e2c15dc..12183f91498 100644 --- a/code/modules/virus2/effect.dm +++ b/code/modules/virus2/effect.dm @@ -104,12 +104,12 @@ ////////////////////////STAGE 4///////////////////////////////// -/datum/disease2/effect/alchdranine +/datum/disease2/effect/doctorsdelight name = "Panacea Effect" stage = 4 activate(var/mob/living/carbon/mob,var/multiplier) - if (mob.reagents.get_reagent_amount("alchdranine") < 1) - mob.reagents.add_reagent("alchdranine", 1) + if (mob.reagents.get_reagent_amount("doctorsdelight") < 1) + mob.reagents.add_reagent("doctorsdelight", 1) /datum/disease2/effect/viralsputum_major name = "Hemoptysis" @@ -382,12 +382,12 @@ /obj/item/clothing/mask/gas/virusclown_hat dropped(mob/user as mob) - canremove = 1 + flags &= ~NODROP ..() equipped(var/mob/user, var/slot) if (slot == slot_l_hand) - canremove = 1 //curses! + flags &= ~NODROP //curses! ..() */ @@ -626,12 +626,12 @@ /obj/item/clothing/glasses/virussunglasses dropped(mob/user as mob) - canremove = 1 + flags &= ~NODROP ..() equipped(var/mob/user, var/slot) if (slot == slot_glasses) - canremove = 0 //curses! + flags |= NODROP //curses! ..() @@ -650,12 +650,12 @@ /obj/item/clothing/mask/gas/virusclown_hat dropped(mob/user as mob) - canremove = 1 + flags &= ~NODROP ..() equipped(var/mob/user, var/slot) if (slot == slot_wear_mask) - canremove = 0 //curses! + flags |= NODROP //curses! ..() @@ -678,12 +678,12 @@ var/list/compatible_mobs = list(/mob/living/carbon/human, /mob/living/carbon/mon voicechange = 1 //NEEEEIIGHH dropped(mob/user as mob) - canremove = 1 + flags &= ~NODROP ..() equipped(var/mob/user, var/slot) if (slot == slot_wear_mask) - canremove = 0 //curses! + flags |= NODROP //curses! ..() diff --git a/code/modules/virus2/helpers.dm b/code/modules/virus2/helpers.dm index e3525797d71..88d95b6839a 100644 --- a/code/modules/virus2/helpers.dm +++ b/code/modules/virus2/helpers.dm @@ -46,7 +46,6 @@ proc/get_infection_chance(var/mob/living/carbon/M, var/vector = "Airborne") //Checks if table-passing table can reach target (5 tile radius) proc/airborne_can_reach(turf/source, turf/target, var/radius=5) var/obj/dummy = new(source) - dummy.flags = FPRINT | TABLEPASS dummy.pass_flags = PASSTABLE for(var/i=0, i[C.name]
([C.ckey]), the [C.job] has been freed due to (Client disconnect for 10 minutes)\n") for(var/obj/item/W in C) - C.drop_from_inventory(W) + C.unEquip(W) del(C) else if(!C.key && C.stat != DEAD && C.brain_op_stage!=4.0) job_master.FreeRole(C.job) message_admins("[C.name] ([C.ckey]), the [C.job] has been freed due to (Client quit BYOND)\n") for(var/obj/item/W in C) - C.drop_from_inventory(W) + C.unEquip(W) del(C) #undef INACTIVITY_KICK */ diff --git a/config/example/config.txt b/config/example/config.txt index 1a53041a540..454dcca2d0c 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -246,6 +246,18 @@ GHOST_INTERACTION ## Default is "python" on Windows, "/usr/bin/env python2" on UNIX. #PYTHON_PATH pythonw +## Defines which Z-levels the station exists on. +STATION_LEVELS 1 + +## Defines which Z-levels are used for admin functionality, such as Central Command and the Syndicate Shuttle +ADMIN_LEVELS 2 + +## Defines which Z-levels which, for example, a Code Red announcement may affect +CONTACT_LEVELS 1;5 + +## Defines all Z-levels a character can typically reach +PLAYER_LEVELS 1;3;4;5;6;7 + ## Expected round length in minutes EXPECTED_ROUND_LENGTH 120 diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index 17667aab4e9..97b9a24eb2f 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/effects/fire.dmi b/icons/effects/fire.dmi index 9e5c0d2db83..da0f4c6271a 100644 Binary files a/icons/effects/fire.dmi and b/icons/effects/fire.dmi differ diff --git a/icons/effects/species.dmi b/icons/effects/species.dmi index d5405066ab9..a4562fd8d75 100644 Binary files a/icons/effects/species.dmi and b/icons/effects/species.dmi differ diff --git a/icons/misc/fullscreen.dmi b/icons/misc/fullscreen.dmi index ec847597fd2..6f9e7d29635 100644 Binary files a/icons/misc/fullscreen.dmi and b/icons/misc/fullscreen.dmi differ diff --git a/icons/misc/fullscreen_544.dmi b/icons/misc/fullscreen_544.dmi new file mode 100644 index 00000000000..ec847597fd2 Binary files /dev/null and b/icons/misc/fullscreen_544.dmi differ diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index f3d08f645c3..0e83c2a3e63 100644 Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index eb984038398..8773d255248 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/mob/belt.dmi b/icons/mob/belt.dmi index bbad97bf8bd..f989cb1ab34 100644 Binary files a/icons/mob/belt.dmi and b/icons/mob/belt.dmi differ diff --git a/icons/mob/custom-synthetic.dmi b/icons/mob/custom-synthetic.dmi index 77cef2656fb..1c61475e89e 100644 Binary files a/icons/mob/custom-synthetic.dmi and b/icons/mob/custom-synthetic.dmi differ diff --git a/icons/mob/feet.dmi b/icons/mob/feet.dmi index eea28466f0a..69e492d24e9 100644 Binary files a/icons/mob/feet.dmi and b/icons/mob/feet.dmi differ diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index c3ac8ef0451..812efd72939 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi index 7ed0f6e3f79..a7f9adf1844 100644 Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ diff --git a/icons/mob/human_races/r_diona.dmi b/icons/mob/human_races/r_diona.dmi index c09acaa9538..f83948951ea 100644 Binary files a/icons/mob/human_races/r_diona.dmi and b/icons/mob/human_races/r_diona.dmi differ diff --git a/icons/mob/human_races/r_golem.dmi b/icons/mob/human_races/r_golem.dmi new file mode 100644 index 00000000000..f9cfb8e157c Binary files /dev/null and b/icons/mob/human_races/r_golem.dmi differ diff --git a/icons/mob/human_races/r_shadow.dmi b/icons/mob/human_races/r_shadow.dmi new file mode 100644 index 00000000000..70450af6902 Binary files /dev/null and b/icons/mob/human_races/r_shadow.dmi differ diff --git a/icons/mob/human_races/r_slime.dmi b/icons/mob/human_races/r_slime.dmi new file mode 100644 index 00000000000..287779d3c7b Binary files /dev/null and b/icons/mob/human_races/r_slime.dmi differ diff --git a/icons/mob/in-hand/changeling.dmi b/icons/mob/in-hand/changeling.dmi new file mode 100644 index 00000000000..ab9e0857312 Binary files /dev/null and b/icons/mob/in-hand/changeling.dmi differ diff --git a/icons/mob/in-hand/guns.dmi b/icons/mob/in-hand/guns.dmi index 9173af72b35..ff8adfd7c5a 100644 Binary files a/icons/mob/in-hand/guns.dmi and b/icons/mob/in-hand/guns.dmi differ diff --git a/icons/mob/in-hand/tools.dmi b/icons/mob/in-hand/tools.dmi index d7070df48f8..c589f2402ce 100644 Binary files a/icons/mob/in-hand/tools.dmi and b/icons/mob/in-hand/tools.dmi differ diff --git a/icons/mob/mask.dmi b/icons/mob/mask.dmi index 2e5468640ea..60e54433a01 100644 Binary files a/icons/mob/mask.dmi and b/icons/mob/mask.dmi differ diff --git a/icons/mob/robots.dmi b/icons/mob/robots.dmi index f0ddc3b8170..39053002542 100644 Binary files a/icons/mob/robots.dmi and b/icons/mob/robots.dmi differ diff --git a/icons/mob/screen1_corgi.dmi b/icons/mob/screen1_corgi.dmi new file mode 100644 index 00000000000..e601d684e5b Binary files /dev/null and b/icons/mob/screen1_corgi.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index bfcb7ce190f..a3d8a405b32 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/mob/talk.dmi b/icons/mob/talk.dmi index 2cd0b40bb18..49aaee9182f 100644 Binary files a/icons/mob/talk.dmi and b/icons/mob/talk.dmi differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index 3f158f68f3f..3d93fb8aef7 100644 Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ diff --git a/icons/mob/uniform_fat.dmi b/icons/mob/uniform_fat.dmi index 7e93cf3901b..21824ea5389 100644 Binary files a/icons/mob/uniform_fat.dmi and b/icons/mob/uniform_fat.dmi differ diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi index 2f91d818b5a..d8f875d1944 100644 Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ diff --git a/icons/obj/barsigns.dmi b/icons/obj/barsigns.dmi index a8d57e8fddc..cacaf71b156 100644 Binary files a/icons/obj/barsigns.dmi and b/icons/obj/barsigns.dmi differ diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi index 83b8c49d86a..584ee26023e 100644 Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index dd1bcd3e70f..f283b7f397c 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index 1bb1b4d4d10..7df20eeb250 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi index 40db65abadf..597ba552949 100644 Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index c8a10b1c4da..ffc1bcef480 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/clothing/ties_overlay.dmi b/icons/obj/clothing/ties_overlay.dmi new file mode 100644 index 00000000000..b4876371591 Binary files /dev/null and b/icons/obj/clothing/ties_overlay.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index 574b1817f97..880b5346d1e 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/icons/obj/contraband.dmi b/icons/obj/contraband.dmi index cbf6e94c3f4..40a73329541 100644 Binary files a/icons/obj/contraband.dmi and b/icons/obj/contraband.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index a83f398a1b3..6d1d9eb401f 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/obj/foodcart.dmi b/icons/obj/foodcart.dmi new file mode 100644 index 00000000000..334eb512993 Binary files /dev/null and b/icons/obj/foodcart.dmi differ diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi index a2dd9d92a9c..cbc9742a6c5 100644 Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ diff --git a/icons/obj/improvised.dmi b/icons/obj/improvised.dmi new file mode 100644 index 00000000000..a6dfa330e8c Binary files /dev/null and b/icons/obj/improvised.dmi differ diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi index 9d85238456b..37ef8e659b7 100644 Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index 3cfdd226e92..d576f993bef 100644 Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ diff --git a/icons/obj/machines/turret_control.dmi b/icons/obj/machines/turret_control.dmi new file mode 100644 index 00000000000..b7c81cd923e Binary files /dev/null and b/icons/obj/machines/turret_control.dmi differ diff --git a/icons/obj/robot_storage.dmi b/icons/obj/robot_storage.dmi index 5a996c01e7e..2382586eee7 100644 Binary files a/icons/obj/robot_storage.dmi and b/icons/obj/robot_storage.dmi differ diff --git a/icons/obj/stock_parts.dmi b/icons/obj/stock_parts.dmi index 1e56e5848dc..d263d057cbc 100644 Binary files a/icons/obj/stock_parts.dmi and b/icons/obj/stock_parts.dmi differ diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index bd5f7a74a3a..30c8906634e 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ diff --git a/icons/obj/toy.dmi b/icons/obj/toy.dmi index 84a99f103c8..cfde5ba0c1b 100644 Binary files a/icons/obj/toy.dmi and b/icons/obj/toy.dmi differ diff --git a/icons/obj/watertank.dmi b/icons/obj/watertank.dmi new file mode 100644 index 00000000000..fb9778719e4 Binary files /dev/null and b/icons/obj/watertank.dmi differ diff --git a/icons/obj/weapons.dmi b/icons/obj/weapons.dmi index ab98bbb87be..5a2601f5283 100644 Binary files a/icons/obj/weapons.dmi and b/icons/obj/weapons.dmi differ diff --git a/icons/turf/walls.dmi b/icons/turf/walls.dmi index c56f7fb8d8c..d977584bd34 100644 Binary files a/icons/turf/walls.dmi and b/icons/turf/walls.dmi differ diff --git a/interface/interface.dm b/interface/interface.dm index 54a26a29cf8..267dfdfaca8 100644 --- a/interface/interface.dm +++ b/interface/interface.dm @@ -13,10 +13,10 @@ src << "The wiki URL is not set in the server configuration." return -#define CHANGELOG "http://nanotrasen.se/phpBB3/viewtopic.php?f=10&t=36" +#define CHANGELOG "https://github.com/ParadiseSS13/Paradise/issues?q=is%3Apr+is%3Aclosed" /client/verb/changes() set name = "Changelog" - set desc = "Visit the forum to check out the changelog." + set desc = "Visit Github to check out the commits." set hidden = 1 if(alert("This will open the changelog in your browser. Are you sure?",,"Yes","No")=="No") @@ -124,7 +124,7 @@ Admin: //adv. hotkey mode verbs, vars located in /code/modules/client/client defines.dm /client/verb/hotkey_toggle()//toggles hotkey mode between on and off, respects selected type - set name = ".Toggle hotkey mode" + set name = ".Toggle Hotkey Mode" hotkeyon = !hotkeyon//toggle the var diff --git a/interface/skin.dmf b/interface/skin.dmf index 96ab4aea9bc..ba3bee45bc9 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -149,11 +149,11 @@ macro "AZERTYoff" is-disabled = false elem name = "F3" - command = "say" + command = ".say" is-disabled = false elem name = "F4" - command = "me" + command = ".me" is-disabled = false elem name = "F5" @@ -347,7 +347,7 @@ macro "AZERTYon" is-disabled = false elem name = "T" - command = "say" + command = ".say" is-disabled = false elem name = "W" @@ -403,11 +403,11 @@ macro "AZERTYon" is-disabled = false elem name = "F3" - command = "say" + command = ".say" is-disabled = false elem name = "F4" - command = "me" + command = ".me" is-disabled = false elem name = "F5" @@ -581,11 +581,11 @@ macro "macro" is-disabled = false elem name = "F3" - command = "say" + command = ".say" is-disabled = false elem name = "F4" - command = "me" + command = ".me" is-disabled = false elem name = "F5" @@ -705,6 +705,10 @@ macro "hotkeymode" name = "CTRL+4" command = "a-intent harm" is-disabled = false + elem + name = "5" + command = ".me" + is-disabled = false elem name = "A+REP" command = ".west" @@ -779,7 +783,7 @@ macro "hotkeymode" is-disabled = false elem name = "T" - command = "say" + command = ".say" is-disabled = false elem "w_key" name = "W+REP" @@ -835,11 +839,11 @@ macro "hotkeymode" is-disabled = false elem name = "F3" - command = "say" + command = ".say" is-disabled = false elem name = "F4" - command = "me" + command = ".me" is-disabled = false elem name = "F5" diff --git a/maps/RandomZLevels/blackmarketpackers.dmm b/maps/RandomZLevels/blackmarketpackers.dmm index defb234b95b..be1160e8830 100644 --- a/maps/RandomZLevels/blackmarketpackers.dmm +++ b/maps/RandomZLevels/blackmarketpackers.dmm @@ -32,7 +32,7 @@ "aF" = (/turf/simulated/shuttle/wall,/area/awaymission/BMPship/Aft) "aG" = (/obj/structure/stool/bed/roller,/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) "aH" = (/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) -"aI" = (/obj/item/weapon/handcuffs,/obj/structure/closet/crate,/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) +"aI" = (/obj/item/weapon/restraints/handcuffs,/obj/structure/closet/crate,/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) "aJ" = (/obj/item/weapon/scalpel,/obj/structure/closet/crate,/obj/item/weapon/tank/anesthetic,/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) "aK" = (/obj/item/bodybag,/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) "aL" = (/obj/item/weapon/storage/box/syringes,/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) diff --git a/maps/RandomZLevels/centcomAway.dmm b/maps/RandomZLevels/centcomAway.dmm index bc0a122da9f..48080199277 100644 --- a/maps/RandomZLevels/centcomAway.dmm +++ b/maps/RandomZLevels/centcomAway.dmm @@ -155,7 +155,7 @@ "cY" = (/obj/machinery/computer/secure_data,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/awaymission/centcomAway/hangar) "cZ" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/awaymission/centcomAway/hangar) "da" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/awaymission/centcomAway/hangar) -"db" = (/obj/structure/table/reinforced,/obj/item/weapon/clipboard,/obj/item/weapon/stamp,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/awaymission/centcomAway/hangar) +"db" = (/obj/structure/table/reinforced,/obj/item/weapon/clipboard,/obj/item/weapon/stamp/granted,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/awaymission/centcomAway/hangar) "dc" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/window/northright,/turf/simulated/floor{tag = "icon-redfull"; icon_state = "redfull"},/area/awaymission/centcomAway/cafe) "dd" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/awaymission/centcomAway/maint) "de" = (/obj/structure/table,/obj/item/device/flash,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/awaymission/centcomAway/hangar) @@ -516,7 +516,7 @@ "jV" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin,/turf/simulated/floor{icon_state = "dark"},/area/awaymission/centcomAway/general) "jW" = (/obj/machinery/computer/secure_data,/turf/simulated/floor{icon_state = "dark"},/area/awaymission/centcomAway/general) "jX" = (/obj/machinery/computer/card,/turf/simulated/floor{icon_state = "dark"},/area/awaymission/centcomAway/general) -"jY" = (/obj/item/weapon/stamp,/obj/structure/table/reinforced,/turf/simulated/floor{tag = "icon-vault (EAST)"; icon_state = "vault"; dir = 4},/area/awaymission/centcomAway/general) +"jY" = (/obj/item/weapon/stamp/granted,/obj/structure/table/reinforced,/turf/simulated/floor{tag = "icon-vault (EAST)"; icon_state = "vault"; dir = 4},/area/awaymission/centcomAway/general) "jZ" = (/obj/structure/table,/obj/item/weapon/firstaid_arm_assembly,/turf/simulated/floor{tag = "icon-vault"; icon_state = "vault"},/area/awaymission/centcomAway/hangar) "ka" = (/obj/structure/table,/obj/item/device/flash,/obj/item/device/flash,/turf/simulated/floor{tag = "icon-vault"; icon_state = "vault"},/area/awaymission/centcomAway/hangar) "kb" = (/obj/structure/table,/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/turf/simulated/floor{tag = "icon-vault"; icon_state = "vault"},/area/awaymission/centcomAway/hangar) @@ -583,14 +583,14 @@ "lk" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor{icon_state = "floor"},/area/awaymission/centcomAway/general) "ll" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor{icon_state = "floor"},/area/awaymission/centcomAway/general) "lm" = (/obj/machinery/photocopier,/turf/simulated/floor{tag = "icon-vault (EAST)"; icon_state = "vault"; dir = 4},/area/awaymission/centcomAway/general) -"ln" = (/obj/item/weapon/clipboard,/obj/structure/table,/obj/item/device/taperecorder,/obj/item/weapon/stamp,/turf/simulated/floor{tag = "icon-vault (NORTH)"; icon_state = "vault"; dir = 1},/area/awaymission/centcomAway/general) +"ln" = (/obj/item/weapon/clipboard,/obj/structure/table,/obj/item/device/taperecorder,/obj/item/weapon/stamp/granted,/turf/simulated/floor{tag = "icon-vault (NORTH)"; icon_state = "vault"; dir = 1},/area/awaymission/centcomAway/general) "lo" = (/obj/machinery/door/window/northright{icon_state = "right"; dir = 2},/turf/simulated/floor{icon_state = "floor"},/area/awaymission/centcomAway/general) "lp" = (/obj/structure/table/reinforced,/obj/machinery/door_control{id = "XCCsec2"; name = "XCC Shutter 2 Control"},/turf/simulated/floor{icon_state = "dark"},/area/awaymission/centcomAway/general) "lq" = (/turf/simulated/floor{dir = 8; icon_state = "red"},/area/awaymission/centcomAway/general) "lr" = (/turf/simulated/floor{icon_state = "red"; dir = 10},/area/awaymission/centcomAway/general) "ls" = (/turf/simulated/floor{icon_state = "red"; dir = 2},/area/awaymission/centcomAway/general) "lt" = (/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/awaymission/centcomAway/general) -"lu" = (/obj/structure/table,/obj/item/weapon/storage/box/handcuffs,/obj/item/weapon/stamp,/turf/simulated/floor{tag = "icon-vault (NORTH)"; icon_state = "vault"; dir = 1},/area/awaymission/centcomAway/general) +"lu" = (/obj/structure/table,/obj/item/weapon/storage/box/handcuffs,/obj/item/weapon/stamp/granted,/turf/simulated/floor{tag = "icon-vault (NORTH)"; icon_state = "vault"; dir = 1},/area/awaymission/centcomAway/general) "lv" = (/obj/machinery/door/airlock/external,/turf/simulated/floor{icon_state = "red"; dir = 10},/area/awaymission/centcomAway/general) "lw" = (/obj/machinery/door/airlock/external,/turf/simulated/floor{icon_state = "green"; dir = 6},/area/awaymission/centcomAway/general) "lx" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/awaymission/centcomAway/general) @@ -629,7 +629,7 @@ "me" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor{tag = "icon-vault (NORTHEAST)"; icon_state = "vault"; dir = 5},/area/awaymission/centcomAway/thunderdome) "mf" = (/obj/structure/stool/bed/chair,/turf/simulated/floor{tag = "icon-redbluefull (WEST)"; icon_state = "redbluefull"; dir = 8},/area/awaymission/centcomAway/thunderdome) "mg" = (/turf/simulated/floor{dir = 8; icon_state = "red"},/area/awaymission/centcomAway/thunderdome) -"mh" = (/obj/structure/rack,/obj/item/weapon/legcuffs/beartrap,/obj/item/weapon/twohanded/fireaxe,/turf/simulated/floor{icon_state = "dark"},/area/awaymission/centcomAway/thunderdome) +"mh" = (/obj/structure/rack,/obj/item/weapon/restraints/legcuffs/beartrap,/obj/item/weapon/twohanded/fireaxe,/turf/simulated/floor{icon_state = "dark"},/area/awaymission/centcomAway/thunderdome) "mi" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/awaymission/centcomAway/thunderdome) "mj" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/awaymission/centcomAway/thunderdome) "mk" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/awaymission/centcomAway/thunderdome) diff --git a/maps/RandomZLevels/challenge.dmm b/maps/RandomZLevels/challenge.dmm index 2804fcfe6a8..697f5f877eb 100644 --- a/maps/RandomZLevels/challenge.dmm +++ b/maps/RandomZLevels/challenge.dmm @@ -119,7 +119,7 @@ "co" = (/turf/simulated/floor/bluegrid,/area/awaymission/challenge/end) "cp" = (/turf/simulated/floor{tag = "icon-vault (WEST)"; icon_state = "vault"; dir = 8},/area/awaymission/challenge/end) "cq" = (/obj/structure/window/reinforced{dir = 8},/turf/space,/area) -"cr" = (/obj/structure/table/woodentable,/obj/item/weapon/melee/chainofcommand,/obj/item/weapon/stamp,/turf/simulated/floor/carpet,/area/awaymission/challenge/end) +"cr" = (/obj/structure/table/woodentable,/obj/item/weapon/melee/chainofcommand,/obj/item/weapon/stamp/granted,/turf/simulated/floor/carpet,/area/awaymission/challenge/end) "cs" = (/obj/structure/table/woodentable,/obj/item/weapon/paper{info = "Congratulations,

Your station has been selected to carry out the Gateway Project.

The equipment will be shipped to you at the start of the next quarter.
You are to prepare a secure location to house the equipment as outlined in the attached documents.

--Nanotrasen Blue Space Research"; name = "Confidential Correspondence, Pg 1"; pixel_x = 0; pixel_y = 0},/obj/item/weapon/folder/blue,/turf/simulated/floor/carpet,/area/awaymission/challenge/end) "ct" = (/obj/structure/table/woodentable,/obj/machinery/light/small/lamp/green{pixel_x = 1; pixel_y = 5},/turf/simulated/floor/carpet,/area/awaymission/challenge/end) "cu" = (/obj/structure/rack,/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced,/turf/simulated/floor/wood,/area/awaymission/challenge/end) diff --git a/maps/RandomZLevels/fileList.txt b/maps/RandomZLevels/fileList.txt index 566dc613557..3c3785c3beb 100644 --- a/maps/RandomZLevels/fileList.txt +++ b/maps/RandomZLevels/fileList.txt @@ -9,7 +9,7 @@ #maps/RandomZLevels/academy.dmm maps/RandomZLevels/beach.dmm -maps/RandomZLevels/blackmarketpackers.dmm +#maps/RandomZLevels/blackmarketpackers.dmm maps/RandomZLevels/challenge.dmm #maps/RandomZLevels/centcomAway.dmm #maps/RandomZLevels/clownplanet.dmm diff --git a/maps/RandomZLevels/moonoutpost19.dmm b/maps/RandomZLevels/moonoutpost19.dmm index c9f561c8109..cf8bcee621f 100644 --- a/maps/RandomZLevels/moonoutpost19.dmm +++ b/maps/RandomZLevels/moonoutpost19.dmm @@ -109,7 +109,7 @@ "ce" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{carbon_dioxide = 48.7; dir = 1; heat_capacity = 1e+006; icon_state = "warning"; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "cf" = (/obj/structure/sign/securearea{pixel_x = 0; pixel_y = 32},/turf/simulated/floor{carbon_dioxide = 48.7; dir = 4; heat_capacity = 1e+006; icon_state = "warningcorner"; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "cg" = (/obj/machinery/light/small{active_power_usage = 0; dir = 4; icon_state = "bulb-broken"; status = 2},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{carbon_dioxide = 48.7; dir = 4; heat_capacity = 1e+006; icon_state = "red"; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) -"ch" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/table,/obj/machinery/cell_charger,/obj/machinery/light/small{dir = 8},/obj/item/weapon/cell/high,/obj/item/weapon/paper{info = "Alright, listen up. If you're reading this, I'm either taking a shit or I've been recalled back to Command. Either way, you'll need to know how to restore power. We've stolen this stuff from Nanotrasen, so all the equipment is jury-rigged. We have generators that work on both plasma and uranium, about 50 sheets should power the outpost for quite a while. If the generators aren't working, which is very likely, take the power cell on the desk and put it into the APC in the hallway. That should get the place running, at least for a little while."; name = "Engineering Instructions"},/turf/simulated/floor/plating{dir = 8; heat_capacity = 1e+006; icon_state = "warnplate"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) +"ch" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/table,/obj/machinery/cell_charger,/obj/machinery/light/small{dir = 8},/obj/item/weapon/stock_parts/cell/high,/obj/item/weapon/paper{info = "Alright, listen up. If you're reading this, I'm either taking a shit or I've been recalled back to Command. Either way, you'll need to know how to restore power. We've stolen this stuff from Nanotrasen, so all the equipment is jury-rigged. We have generators that work on both plasma and uranium, about 50 sheets should power the outpost for quite a while. If the generators aren't working, which is very likely, take the power cell on the desk and put it into the APC in the hallway. That should get the place running, at least for a little while."; name = "Engineering Instructions"},/turf/simulated/floor/plating{dir = 8; heat_capacity = 1e+006; icon_state = "warnplate"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "ci" = (/obj/structure/stool,/turf/simulated/floor/plating{broken = 1; heat_capacity = 1e+006; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "cj" = (/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating{dir = 1; heat_capacity = 1e+006; icon_state = "warnplate"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "ck" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{dir = 4; heat_capacity = 1e+006; icon_state = "warnplatecorner"; tag = "icon-warnplatecorner (EAST)"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) @@ -332,7 +332,7 @@ "gt" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/disposalpipe/segment{desc = "An underfloor disposal pipe. This one has been applied with an acid-proof coating."; dir = 4; name = "Acid-Proof disposal pipe"; unacidable = 1},/obj/machinery/door/poddoor/preopen{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id = "Awaylab"; name = "Acid-Proof containment chamber blast door"; unacidable = 1},/obj/structure/cable,/obj/structure/grille,/obj/structure/window/full/reinforced,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "gu" = (/obj/structure/disposalpipe/segment{desc = "An underfloor disposal pipe. This one has been applied with an acid-proof coating."; dir = 4; name = "Acid-Proof disposal pipe"; unacidable = 1},/obj/structure/alien/weeds,/obj/structure/alien/resin/wall,/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "gv" = (/obj/structure/disposalpipe/segment{desc = "An underfloor disposal pipe. This one has been applied with an acid-proof coating."; dir = 2; icon_state = "pipe-c"; name = "Acid-Proof disposal pipe"; unacidable = 1},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) -"gw" = (/obj/structure/table,/obj/effect/decal/cleanable/dirt,/obj/machinery/cell_charger,/obj/item/weapon/cell/high,/obj/item/device/radio/off,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) +"gw" = (/obj/structure/table,/obj/effect/decal/cleanable/dirt,/obj/machinery/cell_charger,/obj/item/weapon/stock_parts/cell/high,/obj/item/device/radio/off,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "gx" = (/obj/structure/table,/obj/item/weapon/paper{info = "Ivan Volodin Stories:

Entry Won - 28/05/2554:
Hello. I am Crazy Ivan. Boss say I must write. I do good job fixing outpost. Is very good job. Much better than mines. Many nice people. I cause no trouble.

Entry Too - 05/06/2554:
I am finding problem with Booze-O-Mat. Is not problem. I solve very easy. Use yellow tool to make purple light go off. I am good engineer! Bartender will be very happy.

Entry Tree - 08/06/2554:
Bartender is not happy. Security man is not happy. Cannot feel legs, is very cold in freezer. Is not good. Table is jammed into door, have no tools. Is very not good. But, on bright side, found meat! Shall chew to keep spirits up.

Entry Fore - 12/06/2554:
Big nasty purple bug looked at me today. Make nervous. Blue wall wire can be broken, then bad thing happens. Very very bad thing. Man in orange spacesuit wave at me today too. He seem nice. Wonder who was?

Entry Fiv - 15/06/2554:
I eat cornflakes today. Is good day. Sun shine for a while. Was nice. I also take ride on disposals chute. Was fun, but tiny. Get clog out of pipes, was vodka bottle. Is empty. This make many sads.

Entry Sex: 19/06/2554:
Purple bugs jumpy today. When waved, get hiss. Maybe very bad. Maybe just ill. Do not know. Is science problem, is not engineer problem. I eat sandwich. Is glorious job. Wish to never end."; name = "Personal Log - Ivan Volodin"},/turf/simulated/floor/plating{broken = 1; heat_capacity = 1e+006; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "gy" = (/obj/machinery/light/small,/obj/structure/closet/toolcloset,/obj/item/clothing/gloves/yellow,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "gz" = (/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) @@ -568,7 +568,7 @@ "kV" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "0"},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "kW" = (/obj/structure/closet/emcloset,/turf/simulated/floor{dir = 0; heat_capacity = 1e+006; icon_state = "blue"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "kX" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/item/device/multitool,/turf/simulated/floor{dir = 0; heat_capacity = 1e+006; icon_state = "blue"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) -"kY" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor{dir = 0; heat_capacity = 1e+006; icon_state = "blue"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) +"kY" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor{dir = 0; heat_capacity = 1e+006; icon_state = "blue"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "kZ" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{dir = 0; heat_capacity = 1e+006; icon_state = "blue"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "la" = (/obj/structure/stool/bed/chair,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "bar"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "lb" = (/obj/structure/extinguisher_cabinet{pixel_x = 26; pixel_y = 0},/obj/machinery/camera{c_tag = "Kitchen"; dir = 8; network = list("MO19")},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) @@ -711,7 +711,7 @@ "nI" = (/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/turf/simulated/shuttle/wall{icon_state = "swall_f9"; dir = 2},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "nJ" = (/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 6},/area/awaycontent/a3{always_unpowered = 1; has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "nK" = (/obj/machinery/washing_machine,/turf/simulated/floor{carbon_dioxide = 48.7; heat_capacity = 1e+006; icon_state = "barber"; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) -"nL" = (/obj/machinery/light/small{dir = 1},/obj/structure/window/reinforced{dir = 4; layer = 2.9},/obj/structure/table,/obj/structure/bedsheetbin,/obj/item/clothing/tie/black,/obj/item/clothing/under/lawyer/black,/turf/simulated/floor{carbon_dioxide = 48.7; heat_capacity = 1e+006; icon_state = "barber"; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) +"nL" = (/obj/machinery/light/small{dir = 1},/obj/structure/window/reinforced{dir = 4; layer = 2.9},/obj/structure/table,/obj/structure/bedsheetbin,/obj/item/clothing/accessory/black,/obj/item/clothing/under/lawyer/black,/turf/simulated/floor{carbon_dioxide = 48.7; heat_capacity = 1e+006; icon_state = "barber"; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "nM" = (/obj/machinery/alarm{dir = 8; frequency = 1439; locked = 0; pixel_x = 23; pixel_y = 0; req_access = null},/turf/simulated/floor{carbon_dioxide = 48.7; dir = 2; heat_capacity = 1e+006; icon_state = "neutralcorner"; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "nN" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "201"; req_one_access_txt = "0"},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "nO" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) diff --git a/maps/RandomZLevels/spacehotel.dmm b/maps/RandomZLevels/spacehotel.dmm index 95051ed7cf6..78fe2b7b35d 100644 --- a/maps/RandomZLevels/spacehotel.dmm +++ b/maps/RandomZLevels/spacehotel.dmm @@ -2,7 +2,7 @@ "ab" = (/turf/unsimulated/wall,/area) "ac" = (/turf/unsimulated/wall,/area/awaymission) "ad" = (/obj/effect/decal/cleanable/blood/old,/turf/unsimulated/wall,/area/awaymission) -"ae" = (/obj/machinery/power/apc{step_y = 0},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/unsimulated/wall,/area/awaymission) +"ae" = (/obj/machinery/power/apc,/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/unsimulated/wall,/area/awaymission) "af" = (/obj/machinery/power/terminal,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/awaymission) "ag" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating,/area/awaymission) "ah" = (/obj/item/stack/cable_coil/random,/obj/effect/decal/remains/human,/turf/simulated/floor/plating,/area/awaymission) @@ -227,7 +227,7 @@ "es" = (/obj/structure/rack,/obj/item/key,/obj/item/key,/obj/item/key,/obj/item/key,/obj/item/key,/turf/simulated/floor/carpet,/area/awaymission) "et" = (/obj/structure/stool/bed/chair/comfy,/obj/effect/decal/cleanable/flour{desc = "Probably."},/obj/effect/decal/cleanable/pie_smudge,/turf/simulated/floor/carpet,/area/awaymission) "eu" = (/obj/structure/stool/bed/chair/comfy,/obj/effect/decal/cleanable/flour{desc = "Probably."},/obj/effect/decal/cleanable/flour{desc = "Probably."},/obj/effect/decal/cleanable/pie_smudge,/turf/simulated/floor/carpet,/area/awaymission) -"ev" = (/obj/item/weapon/legcuffs,/turf/simulated/floor/engine/cult,/area/awaymission) +"ev" = (/obj/item/weapon/restraints/legcuffs,/turf/simulated/floor/engine/cult,/area/awaymission) "ew" = (/obj/machinery/space_heater,/turf/simulated/floor/carpet,/area/awaymission) "ex" = (/obj/structure/table/woodentable,/turf/simulated/floor/carpet,/area/awaymission) "ey" = (/obj/structure/table,/obj/machinery/computer/security/telescreen{desc = "Not used to spy on hotel rooms."; dir = 1; network = "Hotel"; use_power = 0},/turf/simulated/floor/carpet,/area/awaymission) diff --git a/maps/RandomZLevels/stationCollision.dmm b/maps/RandomZLevels/stationCollision.dmm index 89fe6d73a63..d46caef2830 100644 --- a/maps/RandomZLevels/stationCollision.dmm +++ b/maps/RandomZLevels/stationCollision.dmm @@ -260,7 +260,7 @@ "eZ" = (/turf/simulated/floor,/area/awaymission/northblock) "fa" = (/obj/machinery/light/small,/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/awaymission/northblock) "fb" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/airless{icon_state = "floorscorched2"},/area/awaymission/northblock) -"fc" = (/obj/structure/table,/obj/item/weapon/stock_parts/capacitor,/obj/item/weapon/stock_parts/capacitor{pixel_x = -3},/obj/item/weapon/stock_parts/scanning_module{pixel_x = 3; pixel_y = 3},/obj/item/weapon/stock_parts/scanning_module{pixel_y = -3; step_y = 0},/turf/simulated/floor{icon_state = "showroomfloor"},/area/awaymission/research) +"fc" = (/obj/structure/table,/obj/item/weapon/stock_parts/capacitor,/obj/item/weapon/stock_parts/capacitor{pixel_x = -3},/obj/item/weapon/stock_parts/scanning_module{pixel_x = 3; pixel_y = 3},/obj/item/weapon/stock_parts/scanning_module{pixel_y = -3},/turf/simulated/floor{icon_state = "showroomfloor"},/area/awaymission/research) "fd" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor{icon_state = "showroomfloor"},/area/awaymission/research) "fe" = (/obj/structure/table,/obj/item/weapon/stock_parts/manipulator,/obj/item/weapon/stock_parts/manipulator{pixel_x = -3; pixel_y = 3},/obj/item/weapon/stock_parts/micro_laser{pixel_x = -3; pixel_y = -3},/obj/item/weapon/stock_parts/micro_laser{pixel_x = 3; pixel_y = 3},/turf/simulated/floor{icon_state = "showroomfloor"},/area/awaymission/research) "ff" = (/obj/machinery/computer/crew,/turf/simulated/floor{dir = 4; icon_state = "bluecorner"},/area/awaymission/northblock) diff --git a/maps/RandomZLevels/undergroundoutpost45.dmm b/maps/RandomZLevels/undergroundoutpost45.dmm index 21c5d6950ea..f73599fa3f1 100644 --- a/maps/RandomZLevels/undergroundoutpost45.dmm +++ b/maps/RandomZLevels/undergroundoutpost45.dmm @@ -375,10 +375,10 @@ "hk" = (/obj/machinery/vending/cola,/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "bar"},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) "hl" = (/obj/structure/table/reinforced,/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "bar"},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) "hm" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "bar"},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) -"hn" = (/obj/structure/table,/obj/item/weapon/packageWrap,/obj/item/weapon/reagent_containers/glass/rag,/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "bar"},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) +"hn" = (/obj/structure/table,/obj/item/stack/packageWrap,/obj/item/weapon/reagent_containers/glass/rag,/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "bar"},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) "ho" = (/obj/machinery/vending/boozeomat{req_access_txt = "0"},/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "bar"},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) "hp" = (/obj/structure/extinguisher_cabinet{pixel_x = -25; pixel_y = 0},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{dir = 5; heat_capacity = 1e+006; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) -"hq" = (/obj/structure/table,/obj/item/weapon/packageWrap,/obj/item/weapon/reagent_containers/food/condiment/enzyme{layer = 5},/turf/simulated/floor{dir = 5; heat_capacity = 1e+006; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) +"hq" = (/obj/structure/table,/obj/item/stack/packageWrap,/obj/item/weapon/reagent_containers/food/condiment/enzyme{layer = 5},/turf/simulated/floor{dir = 5; heat_capacity = 1e+006; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) "hr" = (/obj/structure/table,/turf/simulated/floor{dir = 5; heat_capacity = 1e+006; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) "hs" = (/obj/machinery/alarm{dir = 8; frequency = 1439; locked = 0; pixel_x = 23; pixel_y = 0; req_access = null},/obj/machinery/camera{c_tag = "Kitchen"; dir = 8; network = list("UO45")},/obj/structure/table,/obj/machinery/microwave{pixel_x = -3; pixel_y = 6},/turf/simulated/floor{dir = 5; heat_capacity = 1e+006; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) "ht" = (/obj/machinery/gateway{dir = 8},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "vault"},/area/awaycontent/a6{has_gravity = 1; name = "UO45 Gateway"}) @@ -464,7 +464,7 @@ "iV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/awaycontent/a6{has_gravity = 1; name = "UO45 Gateway"}) "iW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "white"},/area/awaycontent/a6{has_gravity = 1; name = "UO45 Gateway"}) "iX" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10; level = 1},/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "white"},/area/awaycontent/a6{has_gravity = 1; name = "UO45 Gateway"}) -"iY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/machinery/light/small{dir = 8},/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "white"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) +"iY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/obj/machinery/light/small{dir = 8},/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "white"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "iZ" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "white"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "ja" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{heat_capacity = 1e+006},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) "jb" = (/obj/machinery/light/small{dir = 8},/obj/machinery/alarm{dir = 4; frequency = 1439; locked = 0; pixel_x = -23; pixel_y = 0; req_access = null},/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "bar"},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) @@ -618,10 +618,10 @@ "lT" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/obj/structure/sign/deathsposal{desc = "A warning sign which reads 'DISPOSAL: LEADS TO EXTERIOR'"; name = "\improper DISPOSAL: LEADS TO EXTERIOR"; pixel_x = 0; pixel_y = -32},/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "bar"},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) "lU" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock/glass{name = "Diner"},/turf/simulated/floor{heat_capacity = 1e+006},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) "lV" = (/obj/machinery/door/firedoor,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/airlock/glass{name = "Diner"},/turf/simulated/floor{heat_capacity = 1e+006},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) -"lW" = (/obj/structure/closet/crate,/obj/item/stack/sheet/mineral/plasma{amount = 26},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a3{has_gravity = 1; name = "UO45 Engineering"}) +"lW" = (/obj/structure/closet/crate,/obj/item/stack/sheet/mineral/plasma{amount = 26},/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a3{has_gravity = 1; name = "UO45 Engineering"}) "lX" = (/obj/machinery/light/small{dir = 1},/obj/machinery/camera{c_tag = "Engineering Secure Storage"; dir = 2; network = list("UO45")},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a3{has_gravity = 1; name = "UO45 Engineering"}) "lY" = (/obj/structure/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/rig,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/rig,/turf/simulated/floor/plating{dir = 8; heat_capacity = 1e+006; icon_state = "warnplate"},/area/awaycontent/a3{has_gravity = 1; name = "UO45 Engineering"}) -"lZ" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/stack/cable_coil{pixel_x = 3; pixel_y = -7},/turf/simulated/floor{dir = 4; heat_capacity = 1e+006; icon_state = "warndark"; tag = "icon-warndark (EAST)"},/area/awaycontent/a6{has_gravity = 1; name = "UO45 Gateway"}) +"lZ" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/obj/item/stack/cable_coil{pixel_x = 3; pixel_y = -7},/turf/simulated/floor{dir = 4; heat_capacity = 1e+006; icon_state = "warndark"; tag = "icon-warndark (EAST)"},/area/awaycontent/a6{has_gravity = 1; name = "UO45 Gateway"}) "ma" = (/turf/simulated/floor{heat_capacity = 1e+006},/area/awaycontent/a6{has_gravity = 1; name = "UO45 Gateway"}) "mb" = (/turf/simulated/floor{burnt = 1; dir = 8; heat_capacity = 1e+006; icon_state = "floorscorched1"; tag = "icon-floorscorched1 (WEST)"},/area/awaycontent/a6{has_gravity = 1; name = "UO45 Gateway"}) "mc" = (/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "white"},/area/awaycontent/a6{has_gravity = 1; name = "UO45 Gateway"}) @@ -787,7 +787,7 @@ "pg" = (/obj/item/weapon/storage/secure/safe{pixel_x = 5; pixel_y = -27},/turf/simulated/floor{dir = 5; heat_capacity = 1e+006; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "ph" = (/obj/structure/filingcabinet,/turf/simulated/floor{dir = 10; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "pi" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door_control{desc = "A remote control-switch whichs locks the research division down in the event of a biohazard leak or contamination."; id = "UO45_biohazard"; name = "Biohazard Door Control"; pixel_x = 0; pixel_y = -24; req_access_txt = "201"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) -"pj" = (/obj/structure/closet/secure_closet{icon_broken = "secbroken"; icon_closed = "sec"; icon_locked = "sec1"; icon_off = "secoff"; icon_opened = "secopen"; icon_state = "sec1"; locked = 1; name = "security officer's locker"; req_access_txt = "201"},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 2; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/item/weapon/handcuffs,/obj/item/device/flash,/obj/item/weapon/reagent_containers/spray/pepper,/turf/simulated/floor{dir = 6; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) +"pj" = (/obj/structure/closet/secure_closet{icon_broken = "secbroken"; icon_closed = "sec"; icon_locked = "sec1"; icon_off = "secoff"; icon_opened = "secopen"; icon_state = "sec1"; locked = 1; name = "security officer's locker"; req_access_txt = "201"},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 2; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/item/weapon/restraints/handcuffs,/obj/item/device/flash,/obj/item/weapon/reagent_containers/spray/pepper,/turf/simulated/floor{dir = 6; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "pk" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{broken = 1; heat_capacity = 1e+006; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "pl" = (/obj/structure/flora/kirbyplants{layer = 5},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{dir = 10; heat_capacity = 1e+006; icon_state = "neutral"},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) "pm" = (/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "neutralcorner"},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) @@ -845,7 +845,7 @@ "qm" = (/obj/machinery/light/small,/obj/structure/sink{dir = 8; icon_state = "sink"; pixel_x = -11; pixel_y = 0},/obj/structure/mirror{pixel_x = -28},/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "freezerfloor"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "qn" = (/obj/structure/toilet{tag = "icon-toilet00 (WEST)"; icon_state = "toilet00"; dir = 8},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "freezerfloor"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "qo" = (/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/weapon/reagent_containers/spray/cleaner,/obj/item/clothing/glasses/hud/health,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{dir = 2; heat_capacity = 1e+006; icon_state = "whitecorner"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) -"qp" = (/obj/structure/table,/obj/machinery/alarm{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/item/weapon/hand_labeler,/obj/item/clothing/tie/stethoscope,/turf/simulated/floor{dir = 2; heat_capacity = 1e+006; icon_state = "whitehall"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) +"qp" = (/obj/structure/table,/obj/machinery/alarm{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/item/weapon/hand_labeler,/obj/item/clothing/accessory/stethoscope,/turf/simulated/floor{dir = 2; heat_capacity = 1e+006; icon_state = "whitehall"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "qq" = (/obj/machinery/vending/medical{req_access_txt = "201"},/turf/simulated/floor{dir = 6; heat_capacity = 1e+006; icon_state = "whitehall"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "qr" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "whitehall"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "qs" = (/obj/structure/stool/bed/chair/wood/normal,/turf/simulated/floor/carpet{heat_capacity = 1e+006},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) @@ -1138,7 +1138,7 @@ "vT" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{heat_capacity = 1e+006},/area/awaycontent/a3{has_gravity = 1; name = "UO45 Engineering"}) "vU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = -32},/obj/machinery/vending/engivend{req_access_txt = "0"},/obj/machinery/camera{c_tag = "Engineering Foyer"; dir = 1; network = list("UO45")},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a3{has_gravity = 1; name = "UO45 Engineering"}) "vV" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/vending/tool,/obj/structure/sign/poster{icon_state = "poster5_legit"; pixel_x = 0; pixel_y = -32; serial_number = 21},/turf/simulated/floor{burnt = 1; dir = 8; heat_capacity = 1e+006; icon_state = "floorscorched2"; tag = "icon-floorscorched2 (WEST)"},/area/awaycontent/a3{has_gravity = 1; name = "UO45 Engineering"}) -"vW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor{dir = 6; heat_capacity = 1e+006; icon_state = "yellow"},/area/awaycontent/a3{has_gravity = 1; name = "UO45 Engineering"}) +"vW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor{dir = 6; heat_capacity = 1e+006; icon_state = "yellow"},/area/awaycontent/a3{has_gravity = 1; name = "UO45 Engineering"}) "vX" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/awaycontent/a3{has_gravity = 1; name = "UO45 Engineering"}) "vY" = (/obj/structure/closet/emcloset,/obj/item/clothing/mask/breath,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 2; heat_capacity = 1e+006; icon_state = "bot"},/area/awaycontent/a3{has_gravity = 1; name = "UO45 Engineering"}) "vZ" = (/obj/structure/closet/firecloset,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 2; heat_capacity = 1e+006; icon_state = "bot"},/area/awaycontent/a3{has_gravity = 1; name = "UO45 Engineering"}) diff --git a/maps/cyberiad.dmm b/maps/cyberiad.dmm index 537fc93ecc7..d389e0d07c3 100644 --- a/maps/cyberiad.dmm +++ b/maps/cyberiad.dmm @@ -10,7 +10,7 @@ "aaj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Prison Gate"; name = "Prison Blast Doors"; opacity = 0},/turf/simulated/floor/plating,/area/security/permabrig) "aak" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Prison Gate"; name = "Prison Blast Doors"; opacity = 0},/turf/simulated/floor/plating,/area/security/permabrig) "aal" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Prison Gate"; name = "Prison Blast Doors"; opacity = 0},/turf/simulated/floor/plating,/area/security/permabrig) -"aam" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall/r_wall,/area) +"aam" = (/turf/simulated/wall/r_wall,/area/security/permabrig) "aan" = (/obj/structure/stool/bed,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/permabrig) "aao" = (/turf/simulated/floor{icon_state = "floorgrime"},/area/security/permabrig) "aap" = (/obj/machinery/camera{c_tag = "Prison Bedroom"; dir = 2; network = list("Prison","SS13")},/obj/machinery/atmospherics/unary/vent_pump,/turf/simulated/floor,/area/security/permabrig) @@ -28,12 +28,12 @@ "aaB" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/permabrig) "aaC" = (/obj/machinery/washing_machine,/turf/simulated/floor{dir = 2; icon_state = "barber"},/area/security/permabrig) "aaD" = (/obj/machinery/newscaster{pixel_y = -28},/obj/structure/table,/obj/item/weapon/pen{layer = 4},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/turf/simulated/floor{icon_state = "floorgrime"},/area/security/permabrig) -"aaE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area) +"aaE" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/security/permabrig) "aaF" = (/obj/structure/table,/obj/item/weapon/dice,/obj/item/device/radio/intercom{desc = "Talk... listen through this."; name = "Station Intercom (Brig Radio)"; pixel_x = -28; pixel_y = 0; wires = 2},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor{icon_state = "neutral"; dir = 8},/area/security/permabrig) "aaG" = (/obj/structure/stool,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/permabrig) "aaH" = (/obj/structure/table,/obj/item/weapon/dice/d20,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/permabrig) "aaI" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{icon_state = "floorgrime"},/area/security/permabrig) -"aaJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area) +"aaJ" = (/turf/simulated/wall,/area/security/permabrig) "aaK" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen{layer = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "neutral"; dir = 8},/area/security/permabrig) "aaL" = (/obj/item/weapon/cigbutt,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/permabrig) "aaM" = (/obj/machinery/light/small{dir = 1},/obj/structure/window/reinforced/tinted{dir = 8; icon_state = "twindow"; tag = ""},/turf/simulated/floor{icon_state = "freezerfloor"},/area/security/permabrig) @@ -62,14 +62,14 @@ "abj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Prison Gate"; name = "Prison Blast Doors"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/plating,/area/security/permabrig) "abk" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Prison Gate"; name = "Prison Blast Doors"; opacity = 0},/obj/machinery/door/airlock/glass_security{name = "Prison Wing"; req_access_txt = "2"},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/permabrig) "abl" = (/obj/machinery/door/firedoor,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Prison Gate"; name = "Prison Blast Doors"; opacity = 0},/obj/machinery/door/airlock/glass_security{name = "Prison Wing"; req_access_txt = "2"},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/permabrig) -"abm" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area) +"abm" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/security/permabrig) "abn" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Prison Gate"; name = "Prison Blast Doors"; opacity = 0},/turf/simulated/floor/plating,/area/security/permabrig) "abo" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor{icon_state = "freezerfloor"},/area/security/permabrig) "abp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/plating,/area/security/permabrig) "abq" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/permabrig) "abr" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/flasher{id = "permaflash"; pixel_x = 28; pixel_y = 0},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/permabrig) -"abs" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/turf/simulated/wall,/area) -"abt" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/wall/r_wall,/area) +"abs" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/security/permabrig) +"abt" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/security/permabrig) "abu" = (/obj/structure/toilet{dir = 1},/turf/simulated/floor{icon_state = "freezerfloor"},/area/security/permabrig) "abv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/permabrig) "abw" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Prison Gate"; name = "Prison Blast Doors"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/plating,/area/security/permabrig) @@ -85,12 +85,12 @@ "abG" = (/obj/machinery/camera{c_tag = "Prison Air Control"; dir = 6; network = list("Prison","SS13")},/obj/machinery/flasher_button{id = "permaflash"; pixel_x = 0; pixel_y = 27},/obj/machinery/hologram/holopad,/turf/simulated/floor/plating,/area/security/permabrig) "abH" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "red"; dir = 9},/area/security/permabrig) "abI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "red"; dir = 5},/area/security/permabrig) -"abJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area) +"abJ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/turf/simulated/wall,/area/security/permabrig) "abK" = (/obj/machinery/camera{c_tag = "Prison Solitary Confinement"; dir = 6; network = list("Prison","SS13")},/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor/plating,/area/security/permabrig) "abL" = (/obj/effect/decal/cleanable/cobweb2,/obj/structure/table,/obj/item/weapon/paper,/obj/machinery/light/small{dir = 1},/obj/item/weapon/pen,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plating,/area/security/permabrig) "abM" = (/obj/structure/grille,/obj/structure/sign/securearea,/turf/simulated/floor/airless{icon_state = "circuit"},/area) "abN" = (/obj/structure/table,/obj/item/weapon/wrench,/obj/machinery/light/small{dir = 8},/obj/item/device/radio/intercom{broadcasting = 0; freerange = 0; frequency = 1475; listening = 1; name = "Station Intercom (Security)"; pixel_x = -30; pixel_y = 0},/turf/simulated/floor/plating,/area/security/permabrig) -"abO" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor/plating,/area/security/permabrig) +"abO" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 5},/turf/simulated/floor/plating,/area/security/permabrig) "abP" = (/obj/machinery/atmospherics/valve{dir = 4},/obj/machinery/light_switch{pixel_y = -25},/turf/simulated/floor/plating,/area/security/permabrig) "abQ" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/machinery/atmospherics/pipe/simple/visible{dir = 9},/turf/simulated/floor/plating,/area/security/permabrig) "abR" = (/turf/simulated/floor/plating,/area/security/permabrig) @@ -101,15 +101,15 @@ "abW" = (/turf/space,/area/vox_station/northwest_solars) "abX" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/light{dir = 8},/turf/simulated/floor{icon_state = "red"; dir = 8},/area/security/permabrig) "abY" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/permabrig) -"abZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area) +"abZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/wall/r_wall,/area/security/permabrig) "aca" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plating,/area/security/permabrig) "acb" = (/obj/structure/stool/bed,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/security/permabrig) -"acc" = (/obj/structure/lattice,/obj/machinery/camera{c_tag = "Brig Secure Armory Exterior North"; dir = 4; network = list("SS13")},/turf/space,/area) +"acc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/security/permabrig) "acd" = (/obj/effect/decal/cleanable/cobweb,/obj/structure/table,/obj/item/clothing/suit/straight_jacket,/obj/item/clothing/glasses/sunglasses/blindfold,/turf/simulated/floor{icon_state = "dark"},/area/security/execution{name = "\improper Prisoner Transfer Center"}) "ace" = (/obj/machinery/alarm{pixel_y = 23},/obj/structure/table,/obj/item/device/radio/electropack,/obj/item/device/assembly/signaler{code = 2; frequency = 1449},/turf/simulated/floor{icon_state = "dark"},/area/security/execution{name = "\improper Prisoner Transfer Center"}) "acf" = (/obj/machinery/power/apc{dir = 1; name = "Prisoner Transfer Center APC"; pixel_x = 0; pixel_y = 25},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/stool/bed/chair{name = "Electric Chair"},/turf/simulated/floor{dir = 8; icon_state = "vault"; tag = "icon-vault (WEST)"},/area/security/execution{name = "\improper Prisoner Transfer Center"}) "acg" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/effect/decal/cleanable/cobweb2,/obj/structure/table,/obj/item/weapon/wrench,/obj/item/weapon/screwdriver,/obj/item/clothing/head/helmet,/obj/machinery/light/small{dir = 1},/turf/simulated/floor{icon_state = "dark"},/area/security/execution{name = "\improper Prisoner Transfer Center"}) -"ach" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area) +"ach" = (/turf/simulated/wall/r_wall,/area/security/execution{name = "\improper Prisoner Transfer Center"}) "aci" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "red"; dir = 8},/area/security/permabrig) "acj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/security/hos) "ack" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/security/hos) @@ -120,7 +120,7 @@ "acp" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/security{name = "Prisoner Transfer Center"; req_access = null; req_access_txt = "1"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "dark"},/area/security/execution{name = "\improper Prisoner Transfer Center"}) "acq" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor{icon_state = "red"; dir = 8},/area/security/permabrig) "acr" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/permabrig) -"acs" = (/obj/item/weapon/secbot_assembly,/turf/simulated/floor/plating,/area) +"acs" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/security/permabrig) "act" = (/obj/structure/grille,/obj/structure/sign/securearea{name = "\improper ARMORY"; pixel_y = 32},/turf/space,/area) "acu" = (/obj/structure/grille,/turf/space,/area) "acv" = (/obj/structure/closet/secure_closet/hos,/turf/simulated/floor{icon_state = "dark"},/area/security/hos) @@ -133,7 +133,7 @@ "acC" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/turf/simulated/floor{icon_state = "dark"},/area/security/execution{name = "\improper Prisoner Transfer Center"}) "acD" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/stool/bed,/turf/simulated/floor{dir = 8; icon_state = "vault"; tag = "icon-vault (WEST)"},/area/security/execution{name = "\improper Prisoner Transfer Center"}) "acE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/light_switch{pixel_x = 27},/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "dark"},/area/security/execution{name = "\improper Prisoner Transfer Center"}) -"acF" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area) +"acF" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/medical/research{name = "Research Division"}) "acG" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "red"; dir = 8},/area/security/permabrig) "acH" = (/obj/structure/rack,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/item/weapon/gun/projectile/shotgun/riot,/obj/machinery/ai_status_display{pixel_x = 0; pixel_y = 32},/turf/simulated/floor{dir = 8; icon_state = "vault"; tag = "icon-vault (WEST)"},/area/security/securearmoury) "acI" = (/obj/machinery/alarm{pixel_y = 23},/obj/structure/window/reinforced{dir = 1},/obj/structure/rack,/obj/item/ammo_box/shotgun/beanbag,/obj/item/ammo_box/shotgun/beanbag,/turf/simulated/floor{dir = 8; icon_state = "vault"; tag = "icon-vault (WEST)"},/area/security/securearmoury) @@ -156,7 +156,7 @@ "acZ" = (/obj/structure/table/woodentable,/turf/simulated/floor/carpet,/area/security/hos) "ada" = (/obj/machinery/door_control{id = "Prison Gate"; name = "Prison Wing Lockdown"; pixel_x = -28; pixel_y = 7; req_access_txt = "2"},/obj/machinery/door_control{id = "Secure Gate"; name = "Brig Lockdown"; pixel_x = -28; pixel_y = -3; req_access_txt = "2"},/turf/simulated/floor{icon_state = "dark"},/area/security/hos) "adb" = (/obj/structure/table/woodentable,/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/turf/simulated/floor{icon_state = "dark"},/area/security/hos) -"adc" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = 0; pixel_y = 10},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/effect/decal/warning_stripes/east,/turf/simulated/floor,/area/security/podbay) +"adc" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = 0; pixel_y = 10},/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/obj/effect/decal/warning_stripes/east,/turf/simulated/floor,/area/security/podbay) "add" = (/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor/engine,/area/security/podbay) "ade" = (/obj/machinery/light{dir = 1; on = 1},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/engine,/area/security/podbay) "adf" = (/obj/machinery/camera{c_tag = "Brig Podbay"; dir = 2; network = list("SS13")},/obj/machinery/door_control{desc = "A remote control-switch for the pod doors."; id = "secpodbay"; name = "Pod Door Control"; pixel_x = 0; pixel_y = 24; req_access_txt = "71"},/turf/simulated/floor/engine,/area/security/podbay) @@ -192,7 +192,7 @@ "adJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "dark"},/area/security/securearmoury) "adK" = (/obj/effect/decal/warning_stripes/east,/turf/simulated/floor{icon_state = "dark"},/area/security/securearmoury) "adL" = (/obj/structure/rack,/obj/item/clothing/suit/armor/riot,/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/window/reinforced{dir = 4},/obj/item/clothing/suit/armor/riot,/obj/item/clothing/suit/armor/riot,/turf/simulated/floor{dir = 8; icon_state = "vault"; tag = "icon-vault (WEST)"},/area/security/securearmoury) -"adM" = (/obj/structure/lattice,/obj/machinery/camera{c_tag = "Brig Secure Armory Exterior South"; dir = 8; network = list("SS13")},/turf/space,/area) +"adM" = (/obj/structure/lattice,/obj/machinery/camera{c_tag = "Brig Secure Armory Exterior North"; dir = 4; network = list("SS13")},/turf/space,/area/security/permabrig) "adN" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/apc{dir = 8; name = "Head of Security APC"; pixel_x = -24},/turf/simulated/floor{icon_state = "dark"},/area/security/hos) "adO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/carpet,/area/security/hos) "adP" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/carpet,/area/security/hos) @@ -258,7 +258,7 @@ "aeX" = (/obj/machinery/door/firedoor,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/door/airlock/glass_command{name = "Head of Security"; req_access_txt = "58"},/obj/structure/disposalpipe/sortjunction{dir = 2; icon_state = "pipe-j2s"; sortType = 7},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor{icon_state = "dark"},/area/security/hos) "aeY" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/hos) "aeZ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/hos) -"afa" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area) +"afa" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/security/execution{name = "\improper Prisoner Transfer Center"}) "afb" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/turf/simulated/floor/plating,/area/security/podbay) "afc" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{name = "Security Pods"; req_access_txt = "71"},/turf/simulated/floor{icon_state = "dark"},/area/security/podbay) "afd" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{name = "Security Pods"; req_access_txt = "71"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/security/podbay) @@ -291,7 +291,7 @@ "afE" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/securehallway) "afF" = (/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/securehallway) "afG" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "red"; dir = 5},/area/security/securehallway) -"afH" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/wall,/area) +"afH" = (/turf/simulated/wall/r_wall,/area/security/hos) "afI" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/structure/table/reinforced,/obj/item/clothing/suit/jacket,/obj/item/clothing/head/beret/sec,/obj/machinery/light_switch{pixel_x = -25},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "dark"},/area/security/podbay) "afJ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "dark"},/area/security/podbay) "afK" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "dark"},/area/security/podbay) @@ -326,7 +326,7 @@ "agn" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "dark"},/area/security/podbay) "ago" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/obj/effect/landmark/start{name = "Security Pod Pilot"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/security/podbay) "agp" = (/obj/machinery/computer/security{network = list("SS13","Research Outpost","Mining Outpost")},/obj/machinery/camera{c_tag = "Brig Pod Pilot's Office"; dir = 8; network = list("SS13")},/turf/simulated/floor{icon_state = "dark"},/area/security/podbay) -"agq" = (/obj/structure/sign/nosmoking_2,/turf/simulated/wall/r_wall,/area) +"agq" = (/turf/simulated/wall/r_wall,/area/security/securearmoury) "agr" = (/turf/space,/area/xenos_station/northwest) "ags" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/power/apc{dir = 1; name = "Interrogation APC"; pixel_x = 0; pixel_y = 25},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/hologram/holopad,/turf/simulated/floor{dir = 8; icon_state = "neutralfull"},/area/security/interrogation) "agt" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{dir = 8; icon_state = "neutralfull"},/area/security/interrogation) @@ -461,7 +461,7 @@ "aiS" = (/obj/structure/table,/obj/item/weapon/storage/fancy/donut_box,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/main) "aiT" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor,/area/security/main) "aiU" = (/obj/machinery/camera{c_tag = "Brig Briefing Room"; dir = 8; network = list("SS13")},/turf/simulated/floor,/area/security/main) -"aiV" = (/obj/structure/sign/securearea,/turf/simulated/wall/r_wall,/area) +"aiV" = (/obj/item/weapon/secbot_assembly,/turf/simulated/floor/plating,/area/security/permabrig) "aiW" = (/obj/item/clothing/ears/earmuffs{pixel_x = -3; pixel_y = -2},/obj/item/clothing/ears/earmuffs,/obj/structure/table/reinforced,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor{icon_state = "red"; dir = 9},/area/security/range) "aiX" = (/turf/simulated/floor{icon_state = "red"},/area/security/range) "aiY" = (/turf/simulated/floor{icon_state = "red"; dir = 9},/area/security/range) @@ -560,7 +560,7 @@ "akN" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/security/main) "akO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor,/area/security/main) "akP" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable,/turf/simulated/floor/plating,/area/security/main) -"akQ" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/table/reinforced,/obj/item/weapon/handcuffs,/obj/item/device/flash,/obj/machinery/light{dir = 8},/obj/structure/disposalpipe/segment,/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/main) +"akQ" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/table/reinforced,/obj/item/weapon/restraints/handcuffs,/obj/item/device/flash,/obj/machinery/light{dir = 8},/obj/structure/disposalpipe/segment,/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/main) "akR" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "red"; dir = 8},/area/security/main) "akS" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor,/area/security/main) "akT" = (/obj/structure/closet/secure_closet/security,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor,/area/security/main) @@ -575,7 +575,7 @@ "alc" = (/obj/structure/closet/secure_closet/brigdoc,/turf/simulated/floor{icon_state = "white"},/area/security/medbay) "ald" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/security/medbay) "ale" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/security/medbay) -"alf" = (/obj/structure/table,/obj/item/clothing/tie/stethoscope,/obj/item/weapon/storage/belt/medical,/obj/item/clothing/glasses/hud/health,/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/security/medbay) +"alf" = (/obj/structure/table,/obj/item/clothing/accessory/stethoscope,/obj/item/weapon/storage/belt/medical,/obj/item/clothing/glasses/hud/health,/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/security/medbay) "alg" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/firstaid/adv,/obj/item/weapon/reagent_containers/syringe/antitoxin,/obj/item/weapon/reagent_containers/syringe/inaprovaline,/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor{icon_state = "white"},/area/security/medbay) "alh" = (/obj/structure/table,/obj/machinery/computer/med_data/laptop,/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/security/medbay) "ali" = (/obj/structure/table,/obj/item/weapon/storage/box/masks{pixel_x = 6; pixel_y = 2},/obj/item/weapon/storage/box/gloves,/turf/simulated/floor{dir = 6; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/security/medbay) @@ -605,7 +605,7 @@ "alG" = (/turf/simulated/shuttle/wall{icon_state = "swall3"; dir = 2},/area/shuttle/siberia/station) "alH" = (/obj/machinery/computer/shuttle_control/labor_camp,/obj/machinery/embedded_controller/radio/simple_docking_controller{id_tag = "labor_shuttle"; pixel_x = -25; pixel_y = 0; req_one_access_txt = "13"; tag_door = "labor_shuttle_hatch"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/siberia/station) "alI" = (/obj/structure/stool/bed/chair/office/dark{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/siberia/station) -"alJ" = (/obj/structure/table,/obj/item/weapon/folder/red,/obj/item/weapon/handcuffs,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/siberia/station) +"alJ" = (/obj/structure/table,/obj/item/weapon/folder/red,/obj/item/weapon/restraints/handcuffs,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/siberia/station) "alK" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/security/prisonershuttle) "alL" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/prisonershuttle) "alM" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/security/prisonershuttle) @@ -620,17 +620,17 @@ "alV" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/item/device/radio/intercom{broadcasting = 0; freerange = 0; frequency = 1475; listening = 1; name = "Station Intercom (Security)"; pixel_x = 30; pixel_y = 0},/turf/simulated/floor{icon_state = "red"; dir = 5},/area/security/prisonershuttle) "alW" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock/glass_medical{id_tag = null; name = "Brig Medical Bay"; req_access_txt = "0"; req_one_access_txt = "63"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/security/medbay) "alX" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/airlock/glass_medical{id_tag = null; name = "Brig Medical Bay"; req_access_txt = "0"; req_one_access_txt = "63"},/turf/simulated/floor{icon_state = "white"},/area/security/medbay) -"alY" = (/obj/structure/sign/securearea,/turf/simulated/wall,/area) +"alY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/security/execution{name = "\improper Prisoner Transfer Center"}) "alZ" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{id_tag = "Brig"; name = "Brig"; req_access_txt = "63"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/security/processing) "ama" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/processing) "amb" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{id_tag = "Brig"; name = "Brig"; req_access_txt = "63"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/security/processing) "amc" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{name = "Warden's Office"; req_access_txt = "3"},/turf/simulated/floor{icon_state = "dark"},/area/security/warden) -"amd" = (/obj/structure/sign/securearea,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area) +"amd" = (/turf/simulated/wall/r_wall,/area/security/podbay) "ame" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/security{name = "Equipment Storage"; req_access_txt = "1"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/security/main) -"amf" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area) +"amf" = (/turf/simulated/wall/r_wall,/area/security/interrogationobs) "amg" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{name = "Security Office"; req_access_txt = "63"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/security/main) "amh" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{name = "Security Office"; req_access_txt = "63"},/turf/simulated/floor,/area/security/main) -"ami" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=1"; dir = 1; freq = 1400; location = "Security"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor/plating,/area) +"ami" = (/turf/simulated/wall/r_wall,/area/security/evidence) "amj" = (/obj/machinery/light/small{dir = 1},/obj/structure/closet/emcloset,/obj/machinery/camera/xray{c_tag = "Brig Escape Pod"; network = list("SS13")},/turf/simulated/floor/plating,/area/maintenance/fsmaint) "amk" = (/turf/simulated/floor/plating,/obj/structure/shuttle/engine/propulsion/burst{dir = 4},/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"; dir = 2},/area/shuttle/escape_pod3/station) "aml" = (/turf/simulated/shuttle/wall{tag = "icon-swall12"; icon_state = "swall12"; dir = 2},/area/shuttle/escape_pod3/station) @@ -726,7 +726,7 @@ "anX" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor{icon_state = "red"},/area/security/brig) "anY" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor,/area/security/brig) "anZ" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "red"; dir = 6},/area/security/brig) -"aoa" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall,/area) +"aoa" = (/obj/structure/lattice,/obj/machinery/camera{c_tag = "Brig Secure Armory Exterior South"; dir = 8; network = list("SS13")},/turf/space,/area/security/permabrig) "aob" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/fsmaint) "aoc" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/fsmaint) "aod" = (/turf/simulated/floor/plating,/obj/structure/shuttle/engine/propulsion/burst{dir = 4},/turf/simulated/shuttle/wall{tag = "icon-swall_f5"; icon_state = "swall_f5"; dir = 2},/area/shuttle/escape_pod3/station) @@ -738,19 +738,19 @@ "aoj" = (/turf/simulated/floor/plating/airless,/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/power/tracker,/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk2"; icon_state = "catwalk2"},/area/solar/auxport) "aok" = (/turf/simulated/shuttle/floor,/area/shuttle/siberia/station) "aol" = (/obj/machinery/mineral/labor_claim_console{machinedir = 1; pixel_x = 30; pixel_y = 0},/obj/machinery/mineral/input,/turf/simulated/shuttle/floor,/area/shuttle/siberia/station) -"aom" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/wall/r_wall,/area) +"aom" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/security/interrogationobs) "aon" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/cable,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/plating,/area/security/prisonershuttle) "aoo" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_security{name = "Prisoner Processing"; req_access_txt = "1"},/turf/simulated/floor{icon_state = "floorgrime"},/area/security/prisonershuttle) "aop" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable,/turf/simulated/floor/plating,/area/security/prisonershuttle) "aoq" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{id_tag = "BrigWest"; name = "Brig"; req_access_txt = "63"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/security/prison/cell_block/B) "aor" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{id_tag = "BrigWest"; name = "Brig"; req_access_txt = "63"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/security/prison/cell_block/B) -"aos" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area) +"aos" = (/turf/simulated/wall/r_wall,/area/security/range) "aot" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{id_tag = "BrigEast"; name = "Brig"; req_access_txt = "63"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/security/prison/cell_block/A) "aou" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{id_tag = "BrigEast"; name = "Brig"; req_access_txt = "63"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/security/prison/cell_block/A) "aov" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/airlock/glass_security{id_tag = "BrigFoyer"; name = "Brig"; req_access_txt = "63"},/turf/simulated/floor,/area/security/lobby) "aow" = (/obj/machinery/door/firedoor,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/airlock/glass_security{id_tag = "BrigFoyer"; name = "Brig"; req_access_txt = "63"},/turf/simulated/floor,/area/security/lobby) -"aox" = (/obj/machinery/door/window/brigdoor{base_state = "rightsecure"; dir = 1; icon_state = "rightsecure"; name = "Secure Door"; req_access_txt = "63"},/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/lobby) -"aoy" = (/obj/machinery/door/window/brigdoor{dir = 1; req_access_txt = "63"},/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/lobby) +"aox" = (/turf/simulated/wall/r_wall,/area/security/securehallway) +"aoy" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/security/podbay) "aoz" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/airlock/glass_security{id_tag = "BrigFoyer"; name = "Brig"; req_access_txt = "63"},/turf/simulated/floor,/area/security/lobby) "aoA" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{id_tag = "Temporary Detainment"; name = "Temporary Detainment"; req_access_txt = "2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/security/prison/cell_block/C) "aoB" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{id_tag = "Temporary Detainment"; name = "Temporary Detainment"; req_access_txt = "2"},/turf/simulated/floor,/area/security/prison/cell_block/C) @@ -759,9 +759,9 @@ "aoE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{name = "Detective"; req_access_txt = "4"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/security/detectives_office) "aoF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/plating,/area/security/detectives_office) "aoG" = (/turf/simulated/wall,/area/maintenance/fsmaint) -"aoH" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area) -"aoI" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area) -"aoJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area) +"aoH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/security/evidence) +"aoI" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/wall,/area/security/podbay) +"aoJ" = (/turf/simulated/wall,/area/security/armoury) "aoK" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "security_outer"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "10;13"},/turf/simulated/floor/plating,/area/maintenance/fsmaint) "aoL" = (/turf/simulated/floor/plating/airless,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk4"; icon_state = "catwalk4"},/area/solar/auxstarboard) "aoM" = (/turf/simulated/floor/plating/airless,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk12"; icon_state = "catwalk12"},/area/solar/auxstarboard) @@ -798,10 +798,10 @@ "apr" = (/obj/structure/closet/secure_closet/brig{id = "Cell 1"; name = "Cell 1 Locker"},/obj/machinery/camera{c_tag = "Brig Cell 1"; dir = 2; network = list("SS13")},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/prison/cell_block/A) "aps" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "red"; dir = 9},/area/security/lobby) "apt" = (/turf/simulated/floor{icon_state = "red"; dir = 5},/area/security/lobby) -"apu" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/plating,/area/security/lobby) -"apv" = (/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/lobby) -"apw" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/lobby) -"apx" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/security/lobby) +"apu" = (/turf/simulated/wall,/area/security/securehallway) +"apv" = (/obj/structure/sign/nosmoking_2,/turf/simulated/wall/r_wall,/area/security/podbay) +"apw" = (/turf/simulated/wall/r_wall,/area/security/interrogation) +"apx" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/security/podbay) "apy" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor{icon_state = "red"; dir = 9},/area/security/lobby) "apz" = (/obj/structure/table,/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/obj/machinery/light_switch{pixel_x = -25},/turf/simulated/floor,/area/security/prison/cell_block/C) "apA" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/floor,/area/security/prison/cell_block/C) @@ -814,7 +814,7 @@ "apH" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) "apI" = (/obj/machinery/light{dir = 1},/obj/machinery/power/apc{dir = 1; name = "Detective APC"; pixel_y = 24},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/table/woodentable,/obj/item/weapon/storage/photo_album{pixel_y = -10},/obj/item/device/camera_film,/obj/item/device/camera_film,/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) "apJ" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/maintenance/fsmaint) -"apK" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area) +"apK" = (/turf/simulated/wall/r_wall,/area/security/main) "apL" = (/obj/structure/rack{dir = 1},/obj/item/clothing/mask/gas,/obj/item/clothing/glasses/sunglasses,/obj/item/weapon/crowbar,/turf/simulated/floor/plating,/area/maintenance/fsmaint) "apM" = (/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/maintenance/fsmaint) "apN" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint) @@ -848,13 +848,13 @@ "aqp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating,/area/security/prison/cell_block/A) "aqq" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor{icon_state = "red"; dir = 8},/area/security/lobby) "aqr" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/lobby) -"aqs" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/security/lobby) -"aqt" = (/obj/machinery/computer/secure_data,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/lobby) -"aqu" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/lobby) -"aqv" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/lobby) +"aqs" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/security/interrogation) +"aqt" = (/turf/simulated/wall,/area/security/main) +"aqu" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/security/main) +"aqv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/security/prisonlockers) "aqw" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "red"; dir = 8},/area/security/lobby) "aqx" = (/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/lobby) -"aqy" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/security/lobby) +"aqy" = (/turf/simulated/wall,/area/security/prisonlockers) "aqz" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; external_pressure_bound = 101; on = 1; pressure_checks = 1},/turf/simulated/floor,/area/security/prison/cell_block/C) "aqA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/security/prison/cell_block/C) "aqB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor,/area/security/prison/cell_block/C) @@ -891,16 +891,16 @@ "arg" = (/obj/machinery/flasher{id = "Cell 1"; pixel_x = 0; pixel_y = -28},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor,/area/security/prison/cell_block/A) "arh" = (/obj/structure/stool/bed,/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/prison/cell_block/A) "ari" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "red"; dir = 8},/area/security/lobby) -"arj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable,/turf/simulated/floor/plating,/area/security/lobby) -"ark" = (/obj/machinery/computer/security{network = list("SS13","Research Outpost","Mining Outpost")},/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/lobby) -"arl" = (/obj/machinery/door_control{desc = "A remote control switch for the brig foyer."; id = "BrigFoyer"; name = "Brig Foyer Doors"; normaldoorcontrol = 1; pixel_x = -5; pixel_y = -35; range = 10},/obj/machinery/door_control{desc = "A remote control switch for the brig doors leading to cells 1-4."; id = "BrigEast"; name = "Brig Cells 1-4 Hallway Doors"; normaldoorcontrol = 1; pixel_x = 5; pixel_y = -25; range = 10},/obj/machinery/door_control{desc = "A remote control switch for the brig doors leading to cells 5 and 6."; id = "BrigWest"; name = "Brig Cells 5-6 Hallway Doors"; normaldoorcontrol = 1; pixel_x = -5; pixel_y = -25; range = 20},/obj/item/device/radio/intercom{broadcasting = 0; freerange = 0; frequency = 1475; listening = 1; name = "Station Intercom (Security)"; pixel_x = 30; pixel_y = 0},/obj/structure/stool/bed/chair/office/dark{dir = 8},/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/lobby) +"arj" = (/turf/simulated/wall,/area/security/medbay) +"ark" = (/turf/simulated/wall/r_wall,/area/security/medbay) +"arl" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/security/medbay) "arm" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/security/prison/cell_block/C) "arn" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/security/prison/cell_block/C) "aro" = (/obj/machinery/door/window/brigdoor{dir = 2; name = "Secure Door"; req_access_txt = "2"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/device/radio/intercom{pixel_x = 28},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor,/area/security/prison/cell_block/C) "arp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/security/prison/cell_block/C) "arq" = (/obj/item/weapon/storage/secure/safe{pixel_x = -23},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) "arr" = (/obj/structure/stool,/turf/simulated/floor/carpet,/area/security/detectives_office) -"ars" = (/obj/structure/table/woodentable,/obj/structure/noticeboard{pixel_x = 30; pixel_y = 0},/obj/item/weapon/book/manual/security_space_law,/obj/item/weapon/handcuffs,/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) +"ars" = (/obj/structure/table/woodentable,/obj/structure/noticeboard{pixel_x = 30; pixel_y = 0},/obj/item/weapon/book/manual/security_space_law,/obj/item/weapon/restraints/handcuffs,/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) "art" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/maintenance/fsmaint) "aru" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/stool,/turf/simulated/floor/plating,/area/maintenance/fsmaint) "arv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/table,/turf/simulated/floor/plating,/area/maintenance/fsmaint) @@ -926,10 +926,10 @@ "arP" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door_timer/cell_1{dir = 4; pixel_x = 32; pixel_y = 0},/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor,/area/security/prison/cell_block/A) "arQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable,/obj/machinery/light{dir = 8},/obj/machinery/power/apc{cell_type = 5000; dir = 8; name = "Security Lobby APC"; pixel_x = -24; pixel_y = 0},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor{icon_state = "red"; dir = 8},/area/security/lobby) "arR" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_Toxins = 1},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/lobby) -"arS" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/security/lobby) -"arT" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/security/lobby) -"arU" = (/obj/structure/table,/obj/machinery/door/firedoor,/obj/machinery/door/window/brigdoor{dir = 2; name = "Secure Door"; req_access_txt = "63"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor,/area/security/lobby) -"arV" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable,/obj/structure/sign/securearea,/turf/simulated/floor/plating,/area/security/lobby) +"arS" = (/turf/simulated/wall/r_wall,/area/security/warden) +"arT" = (/turf/simulated/wall,/area/security/warden) +"arU" = (/obj/structure/sign/securearea,/turf/simulated/wall/r_wall,/area/security/main) +"arV" = (/turf/simulated/wall,/area/security/range) "arW" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/lobby) "arX" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor,/area/security/prison/cell_block/C) "arY" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/turf/simulated/floor,/area/security/prison/cell_block/C) @@ -947,7 +947,7 @@ "ask" = (/obj/structure/table,/obj/item/ashtray/plastic,/turf/simulated/floor/plating,/area/maintenance/fsmaint) "asl" = (/obj/effect/landmark{name = "blobstart"},/obj/structure/stool,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint) "asm" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fsmaint) -"asn" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/wall/r_wall,/area) +"asn" = (/turf/simulated/wall/r_wall,/area/maintenance/fsmaint) "aso" = (/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/valve{dir = 4},/turf/simulated/floor/plating{tag = "icon-warnplate (NORTHWEST)"; icon_state = "warnplate"; dir = 9},/area/maintenance/fsmaint) "asp" = (/obj/structure/stool,/obj/machinery/atmospherics/pipe/simple/visible{dir = 10},/turf/simulated/floor/plating{tag = "icon-warnplate (NORTHEAST)"; icon_state = "warnplate"; dir = 5},/area/maintenance/fsmaint) "asq" = (/obj/structure/cable,/obj/machinery/power/solar{id = "auxsolareast"; name = "Port Auxiliary Solar Array"},/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/solar/auxport) @@ -1001,7 +1001,7 @@ "atm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/security/lobby) "atn" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/turf/simulated/floor,/area/security/lobby) "ato" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/lobby) -"atp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/security/lobby) +"atp" = (/obj/structure/sign/securearea,/turf/simulated/wall,/area/security/processing) "atq" = (/obj/structure/stool/bed/chair{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor,/area/security/prison/cell_block/C) "atr" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 101.325; on = 1; pressure_checks = 1},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor,/area/security/prison/cell_block/C) "ats" = (/turf/simulated/wall,/area/security/prison/cell_block/C) @@ -1016,7 +1016,7 @@ "atB" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fsmaint) "atC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/turf/simulated/floor/plating,/area/maintenance/fsmaint) "atD" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/effect/decal/cleanable/robot_debris,/turf/simulated/floor/plating,/area/maintenance/fsmaint) -"atE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/wall/r_wall,/area) +"atE" = (/obj/structure/sign/securearea,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/security/main) "atF" = (/obj/structure/rack{dir = 1},/obj/item/clothing/suit/fire/firefighter,/obj/item/weapon/tank/oxygen,/obj/item/clothing/mask/gas,/obj/item/weapon/extinguisher,/obj/item/clothing/head/hardhat/red,/obj/item/clothing/glasses/meson,/turf/simulated/floor/plating{tag = "icon-warnplate (SOUTHWEST)"; icon_state = "warnplate"; dir = 10},/area/maintenance/fsmaint) "atG" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating{tag = "icon-warnplate (SOUTHEAST)"; icon_state = "warnplate"; dir = 6},/area/maintenance/fsmaint) "atH" = (/obj/structure/grille{density = 0; icon_state = "brokengrille"},/turf/space,/area) @@ -1044,10 +1044,10 @@ "aud" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "neutral"; dir = 1},/area/security/detectives_office) "aue" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/airlock/maintenance{name = "Detective Maintenance"; req_access_txt = "4"},/turf/simulated/floor{icon_state = "floorgrime"},/area/security/detectives_office) "auf" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/fsmaint) -"aug" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/wall,/area) +"aug" = (/obj/structure/sign/securearea,/turf/simulated/wall,/area/security/main) "auh" = (/obj/machinery/door/firedoor,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/airlock/security{id_tag = "laborexit"; name = "Labor Shuttle"; req_access_txt = "1"},/turf/simulated/floor,/area/security/prisonershuttle) -"aui" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/wall/r_wall,/area) -"auj" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/turf/simulated/wall/r_wall,/area) +"aui" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area/security/main) +"auj" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=1"; dir = 1; freq = 1400; location = "Security"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint) "auk" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/cable,/turf/simulated/floor/plating,/area/security/lobby) "aul" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/security/lobby) "aum" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{name = "Security Lobby"; req_access_txt = "0"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor,/area/security/lobby) @@ -1057,7 +1057,7 @@ "auq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/detectives_office) "aur" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/security/detectives_office) "aus" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/detectives_office) -"aut" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/wall/r_wall,/area) +"aut" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall,/area/security/brig) "auu" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor/plating,/area/maintenance/fsmaint) "auv" = (/obj/machinery/vending/chinese,/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor/wood,/area/crew_quarters/mrchangs) "auw" = (/obj/machinery/vending/chinese,/obj/machinery/light{dir = 1},/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/crew_quarters/mrchangs) @@ -1095,7 +1095,7 @@ "avc" = (/turf/simulated/floor{icon_state = "floorgrime"},/area/security/detectives_office) "avd" = (/obj/structure/stool,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/detectives_office) "ave" = (/obj/machinery/computer/med_data,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/detectives_office) -"avf" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall/r_wall,/area) +"avf" = (/turf/simulated/wall/r_wall,/area/security/prisonershuttle) "avg" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/fsmaint) "avh" = (/obj/structure/stool/bed/chair/wood/wings,/turf/simulated/floor/wood,/area/crew_quarters/mrchangs) "avi" = (/turf/simulated/floor/wood,/area/crew_quarters/mrchangs) @@ -1127,7 +1127,7 @@ "avI" = (/obj/structure/table/woodentable,/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/wood,/area/crew_quarters/mrchangs) "avJ" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/wood,/area/crew_quarters/mrchangs) "avK" = (/obj/structure/table/woodentable,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/wood,/area/crew_quarters/mrchangs) -"avL" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/turf/simulated/wall,/area) +"avL" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/wall/r_wall,/area/security/prisonershuttle) "avM" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor{dir = 2; icon_state = "barber"},/area/civilian/barber) "avN" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 2; icon_state = "barber"},/area/civilian/barber) "avO" = (/obj/structure/stool/bed/chair/barber{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "barber"},/area/civilian/barber) @@ -1160,7 +1160,7 @@ "awp" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "arrivals_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = "13"},/turf/simulated/floor/plating,/area) "awq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/mimeoffice) "awr" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/mimeoffice) -"aws" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/clown{name = "Mime's Office"; req_access_txt = "46"},/turf/simulated/floor,/area/mimeoffice) +"aws" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/mime{name = "Mime's Office"; req_access_txt = "46"},/turf/simulated/floor,/area/mimeoffice) "awt" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "awu" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "magistrate"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/magistrateoffice) "awv" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "magistrate"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/magistrateoffice) @@ -1197,7 +1197,7 @@ "axa" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/storage/briefcase{pixel_x = -2; pixel_y = -5},/obj/item/weapon/storage/briefcase{pixel_x = 3; pixel_y = 0},/obj/machinery/light{dir = 1},/turf/simulated/floor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) "axb" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "lawyer"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/lawoffice) "axc" = (/obj/machinery/light{dir = 8},/turf/simulated/floor{icon_state = "redcorner"; dir = 1},/area/hallway/primary/fore) -"axd" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/wall,/area) +"axd" = (/turf/simulated/wall,/area/security/prisonershuttle) "axe" = (/obj/structure/disposalpipe/junction{tag = "icon-pipe-j1 (EAST)"; icon_state = "pipe-j1"; dir = 4},/turf/simulated/floor/plating,/area/maintenance/fsmaint) "axf" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint) "axg" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fsmaint) @@ -1208,7 +1208,7 @@ "axl" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/turf/simulated/floor/wood,/area/crew_quarters/mrchangs) "axm" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/mrchangs) "axn" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/light/small,/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor/wood,/area/crew_quarters/mrchangs) -"axo" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area) +"axo" = (/turf/simulated/wall,/area/security/prison/cell_block/B) "axp" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/turf/simulated/floor{dir = 2; icon_state = "barber"},/area/civilian/barber) "axq" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor{dir = 2; icon_state = "barber"},/area/civilian/barber) "axr" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating,/area/crew_quarters/fitness) @@ -1224,7 +1224,7 @@ "axB" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "axC" = (/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "axD" = (/turf/simulated/floor/plating/airless,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk3"; icon_state = "catwalk3"},/area/solar/auxport) -"axE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/wall,/area) +"axE" = (/turf/simulated/wall,/area/security/prison/cell_block/A) "axF" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/wood,/area/mimeoffice) "axG" = (/turf/simulated/floor/wood,/area/mimeoffice) "axH" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/wood,/area/mimeoffice) @@ -1236,14 +1236,14 @@ "axN" = (/turf/simulated/floor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) "axO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "lawyer"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/lawoffice) "axP" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating,/area/maintenance/fsmaint) -"axQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area) +"axQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/security/prison/cell_block/A) "axR" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint) -"axS" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/turf/simulated/wall,/area) +"axS" = (/obj/machinery/door/window/brigdoor{base_state = "rightsecure"; dir = 1; icon_state = "rightsecure"; name = "Secure Door"; req_access_txt = "63"},/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/brig) "axT" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass{name = "Mr. Chang's"},/turf/simulated/floor,/area/crew_quarters/mrchangs) -"axU" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area) -"axV" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/turf/simulated/wall,/area) +"axU" = (/turf/simulated/wall,/area/security/brig) +"axV" = (/obj/machinery/door/window/brigdoor{dir = 1; req_access_txt = "63"},/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/brig) "axW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass{name = "Barber Shop"},/turf/simulated/floor{dir = 2; icon_state = "barber"},/area/civilian/barber) -"axX" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/wall,/area) +"axX" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/security/detectives_office) "axY" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/crew_quarters/fitness) "axZ" = (/turf/simulated/floor/engine{name = "Holodeck Projector Floor"},/area/holodeck/alphadeck) "aya" = (/turf/simulated/wall/r_wall,/area/hallway/secondary/entry) @@ -1308,14 +1308,14 @@ "azh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/carpet,/area/magistrateoffice) "azi" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/structure/stool/bed/chair/comfy/black,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/carpet,/area/magistrateoffice) "azj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/structure/table/reinforced,/obj/item/device/megaphone,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/carpet,/area/magistrateoffice) -"azk" = (/obj/structure/table/reinforced,/obj/machinery/photocopier/faxmachine{department = "Internal Affairs"},/turf/simulated/floor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) +"azk" = (/obj/structure/table/reinforced,/obj/machinery/photocopier/faxmachine{department = "Internal Affairs Office"},/turf/simulated/floor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) "azl" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/turf/simulated/floor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) "azm" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/obj/effect/landmark/start{name = "Internal Affairs Agent"},/turf/simulated/floor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) "azn" = (/obj/structure/table/reinforced,/turf/simulated/floor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) "azo" = (/obj/structure/table/reinforced,/obj/item/weapon/folder/yellow,/obj/item/weapon/folder/yellow,/obj/item/weapon/stamp/law,/turf/simulated/floor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) "azp" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/effect/landmark/start{name = "Internal Affairs Agent"},/turf/simulated/floor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) "azq" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) -"azr" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/wall,/area) +"azr" = (/turf/simulated/wall,/area/security/detectives_office) "azs" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/effect/landmark{name = "JoinLateCryo"},/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/sleep) "azt" = (/turf/simulated/floor{dir = 8; icon_state = "neutral"},/area/crew_quarters/fitness) "azu" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/crew_quarters/fitness) @@ -1341,7 +1341,7 @@ "azO" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "azP" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "azQ" = (/obj/machinery/space_heater,/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) -"azR" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "eva_airlock"; name = "exterior access button"; pixel_x = 0; pixel_y = 25; req_access_txt = "13"},/turf/simulated/floor/plating/airless,/area/maintenance/fpmaint) +"azR" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area/security/detectives_office) "azS" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "eva_outer"; locked = 1; name = "EVA External Access"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/airless{icon_state = "circuit"},/area/maintenance/fpmaint) "azT" = (/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "eva_sensor"; pixel_x = 0; pixel_y = 25},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "eva_pump"},/turf/simulated/floor/plating,/area/maintenance/fpmaint) "azU" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1379; id_tag = "eva_airlock"; name = "EVA Airlock Console"; pixel_y = 25; req_access_txt = "0"; req_one_access_txt = "1;5;11;18;24"; tag_airpump = "eva_pump"; tag_chamber_sensor = "eva_sensor"; tag_exterior_door = "eva_outer"; tag_interior_door = "eva_inner"},/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 1},/turf/simulated/floor/plating,/area/maintenance/fpmaint) @@ -1369,7 +1369,7 @@ "aAq" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "redcorner"; dir = 1},/area/hallway/primary/fore) "aAr" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "redcorner"; dir = 4},/area/hallway/primary/fore) "aAs" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/fsmaint) -"aAt" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/wall,/area) +"aAt" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint) "aAu" = (/obj/machinery/light{dir = 8},/obj/item/device/radio/intercom{freerange = 0; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -30},/obj/effect/landmark{name = "JoinLateCryo"},/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/sleep) "aAv" = (/obj/machinery/light{dir = 8},/turf/simulated/floor{dir = 8; icon_state = "neutral"},/area/crew_quarters/fitness) "aAw" = (/obj/structure/stool{pixel_y = 8},/turf/simulated/floor,/area/crew_quarters/fitness) @@ -1395,15 +1395,15 @@ "aAQ" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plating,/area/hallway/secondary/entry) "aAR" = (/obj/structure/closet,/obj/item/weapon/storage/backpack,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "aAS" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) -"aAT" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating/airless,/area/maintenance/fpmaint) +"aAT" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint) "aAU" = (/obj/machinery/light/small,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/fpmaint) "aAV" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "eva_pump"},/obj/machinery/camera{c_tag = "EVA Airlock"; dir = 1},/turf/simulated/floor/plating,/area/maintenance/fpmaint) "aAW" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "eva_inner"; locked = 1; name = "EVA Internal Access"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/maintenance/fpmaint) "aAX" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/oil,/turf/simulated/floor/plating,/area/maintenance/fpmaint) "aAY" = (/turf/simulated/floor/plating,/area/maintenance/fpmaint) "aAZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/fpmaint) -"aBa" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/wall,/area) -"aBb" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/wall,/area) +"aBa" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint) +"aBb" = (/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/brig) "aBc" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/camera{c_tag = "Fore Primary Hallway South"; dir = 4; network = list("SS13")},/obj/machinery/power/apc{dir = 8; name = "Fore Primary Hallway APC"; pixel_x = -24},/turf/simulated/floor{icon_state = "redcorner"; dir = 1},/area/hallway/primary/fore) "aBd" = (/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 31},/turf/simulated/floor{icon_state = "redcorner"; dir = 4},/area/hallway/primary/fore) "aBe" = (/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/sleep) @@ -1521,7 +1521,7 @@ "aDm" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass{name = "Holodeck Door"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor,/area/crew_quarters/fitness) "aDn" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/light/small,/obj/machinery/light_switch{pixel_y = -25},/turf/simulated/floor,/area/crew_quarters/fitness) "aDo" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor,/area/crew_quarters/fitness) -"aDp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area) +"aDp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/plating,/area/security/brig) "aDq" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "solar_chapel_outer"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "10;13"},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "aDr" = (/obj/machinery/light_construct/small{dir = 8},/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood{broken = 1; icon_state = "wood-broken"},/area/maintenance/abandonedbar) "aDs" = (/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/turf/simulated/floor/wood{broken = 1; icon_state = "wood-broken"},/area/maintenance/abandonedbar) @@ -1570,7 +1570,7 @@ "aEj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/fsmaint) "aEk" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/apc{dir = 8; name = "Dormitories APC"; pixel_x = -25},/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/sleep) "aEl" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/sleep) -"aEm" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/wall,/area) +"aEm" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/security/brig) "aEn" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{dir = 8; icon_state = "neutral"},/area/crew_quarters/fitness) "aEo" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor,/area/crew_quarters/fitness) "aEp" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor,/area/crew_quarters/fitness) @@ -1589,7 +1589,7 @@ "aEC" = (/obj/structure/stool,/obj/machinery/light,/turf/simulated/floor{icon_state = "green"; dir = 4},/area/crew_quarters/fitness) "aED" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/crew_quarters/fitness) "aEE" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/crew_quarters/fitness) -"aEF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area) +"aEF" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/brig) "aEG" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "solar_chapel_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1379; id_tag = "solar_chapel_pump"},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1379; id_tag = "solar_chapel_airlock"; pixel_x = 25; req_access_txt = "13"; tag_airpump = "solar_chapel_pump"; tag_chamber_sensor = "solar_chapel_sensor"; tag_exterior_door = "solar_chapel_outer"; tag_interior_door = "solar_chapel_inner"},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "aEH" = (/obj/machinery/vending/autodrobe,/turf/simulated/floor/plating,/area/maintenance/abandonedbar) "aEI" = (/obj/item/weapon/shard,/obj/item/stack/rods,/obj/item/weapon/airlock_electronics,/turf/simulated/floor/plating{dir = 9; icon_regular_floor = "escape"},/area/maintenance/abandonedbar) @@ -1650,10 +1650,10 @@ "aFL" = (/turf/simulated/floor{tag = "icon-whitehall (WEST)"; icon_state = "whitehall"; dir = 8},/area/crew_quarters/fitness) "aFM" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/crew_quarters/fitness) "aFN" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/crew_quarters/fitness) -"aFO" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area) +"aFO" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/fsmaint) "aFP" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "solar_chapel_inner"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) -"aFQ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area) -"aFR" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area) +"aFQ" = (/obj/machinery/computer/secure_data,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/brig) +"aFR" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/security/brig) "aFS" = (/obj/machinery/light_construct/small{dir = 1},/turf/simulated/floor/plating{dir = 4; icon_regular_floor = "whitecorner"},/area/maintenance/abandonedbar) "aFT" = (/obj/item/trash/cheesie,/turf/simulated/floor{icon_state = "whitehall"; dir = 5},/area/maintenance/abandonedbar) "aFU" = (/obj/structure/door_assembly,/turf/simulated/floor/plating,/area/maintenance/abandonedbar) @@ -1789,7 +1789,7 @@ "aIu" = (/obj/structure/table,/obj/machinery/alarm{pixel_y = 23},/obj/item/device/t_scanner,/turf/simulated/floor,/area/storage/primary) "aIv" = (/obj/structure/table,/obj/machinery/camera{c_tag = "Primary Tool Storage"},/obj/machinery/requests_console{department = "Tool Storage"; departmentType = 0; pixel_y = 30},/obj/item/device/assembly/igniter{pixel_x = -8; pixel_y = -4},/obj/item/device/assembly/igniter,/obj/item/weapon/screwdriver{pixel_y = 16},/turf/simulated/floor,/area/storage/primary) "aIw" = (/obj/structure/table,/obj/item/device/radio/intercom{broadcasting = 0; name = "Station Intercom (General)"; pixel_y = 20},/obj/item/device/assembly/signaler,/obj/item/device/assembly/signaler,/obj/item/device/multitool,/obj/item/device/multitool{pixel_x = 4},/turf/simulated/floor,/area/storage/primary) -"aIx" = (/obj/structure/table,/obj/machinery/light_switch{pixel_y = 28},/obj/machinery/cell_charger,/obj/item/weapon/cell/high,/turf/simulated/floor,/area/storage/primary) +"aIx" = (/obj/structure/table,/obj/machinery/light_switch{pixel_y = 28},/obj/machinery/cell_charger,/obj/item/weapon/stock_parts/cell/high,/turf/simulated/floor,/area/storage/primary) "aIy" = (/obj/structure/table,/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/item/weapon/storage/toolbox/mechanical,/turf/simulated/floor,/area/storage/primary) "aIz" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{d2 = 2; icon_state = "0-2"},/turf/simulated/floor,/area/storage/primary) "aIA" = (/obj/machinery/vending/tool,/turf/simulated/floor,/area/storage/primary) @@ -1828,7 +1828,7 @@ "aJh" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/apc{dir = 8; name = "Fore Starboard Solar APC"; pixel_x = -25; pixel_y = 3},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "aJi" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "aJj" = (/obj/machinery/camera{c_tag = "Fore Starboard Solars"; dir = 1; network = list("SS13")},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/smes{charge = 0},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) -"aJk" = (/turf/simulated/wall/r_wall{desc = "A specially coated wall that resists temperatures for Science"; max_temperature = 1e+009; name = "Coated Reinforced Wall"},/area) +"aJk" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/brig) "aJl" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aJm" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aJn" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) @@ -1840,7 +1840,7 @@ "aJt" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aJu" = (/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aJv" = (/turf/simulated/wall/r_wall,/area/maintenance/fsmaint2) -"aJw" = (/obj/machinery/door/poddoor{id = "chapelgun"; name = "Chapel Launcher Door"},/turf/simulated/floor/plating,/area) +"aJw" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/brig) "aJx" = (/turf/simulated/shuttle/wall{icon_state = "swall11"; dir = 2},/area/shuttle/arrival/station) "aJy" = (/obj/effect/landmark{name = "HONKsquad"},/obj/structure/closet/walllocker/emerglocker/north,/turf/simulated/shuttle/floor,/area/shuttle/arrival/station) "aJz" = (/turf/simulated/shuttle/floor,/area/shuttle/arrival/station) @@ -1882,7 +1882,7 @@ "aKj" = (/obj/structure/table,/obj/item/device/radio{pixel_y = 6},/obj/item/device/radio{pixel_x = 6; pixel_y = 4},/obj/item/device/radio{pixel_x = -6; pixel_y = 4},/obj/item/device/radio,/turf/simulated/floor,/area/gateway) "aKk" = (/obj/structure/sign/biohazard{pixel_x = 32},/obj/structure/table,/obj/machinery/recharger{pixel_y = 4},/turf/simulated/floor,/area/gateway) "aKl" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/clothing/shoes/magboots{pixel_y = -5},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) -"aKm" = (/obj/structure/table/reinforced,/obj/machinery/cell_charger,/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/stack/cable_coil{pixel_x = 3; pixel_y = -7},/obj/item/stack/cable_coil{pixel_x = 3; pixel_y = -7},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/ai_monitored/storage/eva) +"aKm" = (/obj/structure/table/reinforced,/obj/machinery/cell_charger,/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/obj/item/stack/cable_coil{pixel_x = 3; pixel_y = -7},/obj/item/stack/cable_coil{pixel_x = 3; pixel_y = -7},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/ai_monitored/storage/eva) "aKn" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) "aKo" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/table/reinforced,/obj/item/weapon/book/manual/evaguide,/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/ai_monitored/storage/eva) "aKp" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/clothing/shoes/magboots,/obj/item/weapon/tank/nitrogen,/obj/item/clothing/suit/space/eva/vox,/obj/item/clothing/mask/breath/vox,/obj/item/clothing/head/helmet/space/eva/vox,/turf/simulated/floor{dir = 8; icon_state = "vault"; tag = "icon-vault (WEST)"},/area/ai_monitored/storage/eva) @@ -1893,7 +1893,7 @@ "aKu" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock{name = "Unisex Restrooms"; req_access_txt = "0"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aKv" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aKw" = (/obj/machinery/power/apc{dir = 4; name = "Dormitory Bathrooms APC"; pixel_x = 26; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) -"aKx" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/sign/poster{pixel_x = 0; pixel_y = 0},/turf/simulated/wall,/area) +"aKx" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/security/prison/cell_block/C) "aKy" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/bar) "aKz" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/floor/wood,/area/crew_quarters/bar) "aKA" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/structure/closet/gmcloset{icon_closed = "black"; icon_state = "black"; name = "formal wardrobe"},/obj/machinery/light/small{dir = 4},/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor/wood,/area/crew_quarters/bar) @@ -1908,7 +1908,7 @@ "aKJ" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aKK" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aKL" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) -"aKM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area) +"aKM" = (/obj/machinery/computer/security{network = list("SS13","Research Outpost","Mining Outpost")},/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/brig) "aKN" = (/obj/machinery/door/airlock/maintenance{name = "Chapel Maintenance"; req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aKO" = (/turf/simulated/floor/plating{tag = "icon-warnplate (NORTH)"; icon_state = "warnplate"; dir = 1},/area/chapel/main) "aKP" = (/turf/space,/area/shuttle/escape/station) @@ -1980,11 +1980,11 @@ "aMd" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aMe" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aMf" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/maintenance/fsmaint2) -"aMg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/wall,/area) -"aMh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/wall,/area) +"aMg" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable,/turf/simulated/floor/plating,/area/security/brig) +"aMh" = (/obj/machinery/door_control{desc = "A remote control switch for the brig foyer."; id = "BrigFoyer"; name = "Brig Foyer Doors"; normaldoorcontrol = 1; pixel_x = -5; pixel_y = -35; range = 10},/obj/machinery/door_control{desc = "A remote control switch for the brig doors leading to cells 1-4."; id = "BrigEast"; name = "Brig Cells 1-4 Hallway Doors"; normaldoorcontrol = 1; pixel_x = 5; pixel_y = -25; range = 10},/obj/machinery/door_control{desc = "A remote control switch for the brig doors leading to cells 5 and 6."; id = "BrigWest"; name = "Brig Cells 5-6 Hallway Doors"; normaldoorcontrol = 1; pixel_x = -5; pixel_y = -25; range = 20},/obj/item/device/radio/intercom{broadcasting = 0; freerange = 0; frequency = 1475; listening = 1; name = "Station Intercom (Security)"; pixel_x = 30; pixel_y = 0},/obj/structure/stool/bed/chair/office/dark{dir = 8},/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/brig) "aMi" = (/obj/machinery/door/airlock/maintenance{name = "Library Maintenance"; req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aMj" = (/obj/item/device/radio/intercom{pixel_y = 25},/obj/structure/table/woodentable,/obj/item/weapon/dice/d20,/obj/item/weapon/dice,/turf/simulated/floor/wood,/area/library) -"aMk" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/packageWrap,/turf/simulated/floor/wood,/area/library) +"aMk" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/stack/packageWrap,/turf/simulated/floor/wood,/area/library) "aMl" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/turf/simulated/floor/wood,/area/library) "aMm" = (/obj/machinery/door/airlock/maintenance{name = "Crematorium Maintenance"; req_access_txt = "27"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aMn" = (/obj/structure/closet/wardrobe/chaplain_black,/obj/item/device/radio/intercom{pixel_y = 25},/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) @@ -1992,7 +1992,7 @@ "aMp" = (/obj/machinery/camera{c_tag = "Chapel Chaplain's Office"; dir = 2; network = list("SS13")},/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) "aMq" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/alarm{pixel_y = 25},/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) "aMr" = (/obj/structure/closet/coffin,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor{icon_state = "dark"},/area/chapel/office) -"aMs" = (/obj/structure/closet/coffin,/obj/machinery/door/window/eastleft{name = "Coffin Storage"; req_access_txt = "22"},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) +"aMs" = (/turf/simulated/wall/r_wall,/area/security/prison/cell_block/B) "aMt" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) "aMu" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) "aMv" = (/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) @@ -2000,7 +2000,7 @@ "aMx" = (/obj/machinery/door/window{dir = 8; name = "Mass Driver"; req_access_txt = "22"},/obj/machinery/mass_driver{dir = 1; id = "chapelgun"},/turf/simulated/floor/plating{tag = "icon-warnplate (WEST)"; icon_state = "warnplate"; dir = 8},/area/chapel/main) "aMy" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor,/area/escapepodbay) "aMz" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical,/obj/item/weapon/crowbar/red,/turf/simulated/floor,/area/escapepodbay) -"aMA" = (/obj/structure/table,/obj/item/weapon/storage/belt/utility,/obj/item/weapon/cell,/obj/item/device/flashlight,/turf/simulated/floor,/area/escapepodbay) +"aMA" = (/obj/structure/table,/obj/item/weapon/storage/belt/utility,/obj/item/weapon/stock_parts/cell,/obj/item/device/flashlight,/turf/simulated/floor,/area/escapepodbay) "aMB" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/tank/emergency_oxygen/engi,/obj/item/weapon/tank/emergency_oxygen/engi,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas{pixel_x = -3; pixel_y = -3},/obj/structure/extinguisher_cabinet{pixel_x = -5; pixel_y = 30},/obj/effect/decal/warning_stripes/east,/turf/simulated/floor,/area/escapepodbay) "aMC" = (/obj/machinery/alarm{pixel_y = 25},/turf/simulated/floor/engine,/area/escapepodbay) "aMD" = (/obj/machinery/light{dir = 1},/turf/simulated/floor/engine,/area/escapepodbay) @@ -2012,7 +2012,7 @@ "aMJ" = (/obj/structure/window/full/shuttle,/obj/structure/grille,/turf/simulated/shuttle/plating,/area/shuttle/arrival/station) "aMK" = (/obj/effect/landmark{name = "Observer-Start"},/turf/simulated/shuttle/floor,/area/shuttle/arrival/station) "aML" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 4; icon_state = "whitecorner"},/area/hallway/secondary/entry) -"aMM" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/border_only,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/airlock/security{name = "Security Checkpoint"; req_access = null; req_access_txt = "1"},/turf/simulated/floor,/area/hallway/secondary/entry) +"aMM" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/border_only,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/airlock/security{name = "Security Checkpoint"; req_access = null; req_access_txt = "1"},/turf/simulated/floor,/area/security/checkpoint2) "aMN" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/security/checkpoint2) "aMO" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/obj/machinery/door/window/brigdoor{dir = 1; name = "Security Checkpoint"; req_access_txt = "63"},/turf/simulated/floor{icon_state = "delivery"},/area/security/checkpoint2) "aMP" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) @@ -2025,7 +2025,7 @@ "aMW" = (/obj/structure/stool{pixel_y = 8},/obj/effect/landmark/start{name = "Civilian"},/turf/simulated/floor,/area/storage/primary) "aMX" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/turf/simulated/floor,/area/storage/primary) "aMY" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor,/area/storage/primary) -"aMZ" = (/obj/structure/table,/obj/item/weapon/weldingtool,/obj/item/weapon/crowbar,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/turf/simulated/floor,/area/storage/primary) +"aMZ" = (/obj/structure/table,/obj/item/weapon/weldingtool,/obj/item/weapon/crowbar,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/turf/simulated/floor,/area/storage/primary) "aNa" = (/obj/structure/sign/securearea,/turf/simulated/wall/r_wall,/area/security/nuke_storage) "aNb" = (/obj/machinery/door/airlock/vault{icon_state = "door_locked"; locked = 1; req_access_txt = "53"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/security/nuke_storage) "aNc" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable{d2 = 4; icon_state = "0-4"},/turf/simulated/floor,/area/gateway) @@ -2037,7 +2037,7 @@ "aNi" = (/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/central/north) "aNj" = (/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/hallway/primary/central/north) "aNk" = (/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "blue"; dir = 4},/area/hallway/primary/central/north) -"aNl" = (/obj/structure/sign/directions/security{dir = 1; pixel_y = 7},/turf/simulated/wall,/area) +"aNl" = (/turf/simulated/wall/r_wall,/area/security/prison/cell_block/A) "aNm" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/fsmaint) "aNn" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass{name = "Dormitories"; req_access_txt = "0"},/turf/simulated/floor{dir = 8; icon_state = "neutral"},/area/crew_quarters/fitness) "aNo" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass{name = "Dormitories"; req_access_txt = "0"},/turf/simulated/floor{icon_state = "neutral"; dir = 4},/area/crew_quarters/fitness) @@ -2045,18 +2045,18 @@ "aNq" = (/obj/machinery/door/airlock{name = "Unit 1"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aNr" = (/obj/machinery/door/airlock{name = "Unit 2"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aNs" = (/obj/machinery/door/airlock{name = "Unit B"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) -"aNt" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/wall,/area) +"aNt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/security/brig) "aNu" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/structure/sign/securearea{desc = "Under the painting a plaque reads: 'While the meat grinder may not have spared you, fear not. Not one part of you has gone to waste... You were delicious.'"; icon_state = "monkey_painting"; name = "Mr. Deempisi portrait"; pixel_x = -28; pixel_y = 4},/obj/structure/reagent_dispensers/beerkeg,/turf/simulated/floor/wood,/area/crew_quarters/bar) "aNv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/disposalpipe/segment,/turf/simulated/floor/wood,/area/crew_quarters/bar) "aNw" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/door/window/southleft{tag = "icon-left (WEST)"; name = "Bar Delivery"; icon_state = "left"; dir = 8; req_access_txt = "25"; base_state = "left"},/obj/effect/decal/warning_stripes/yellow,/turf/simulated/floor,/area/crew_quarters/bar) -"aNx" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/machinery/navbeacon{codes_txt = "delivery;dir=2"; freq = 1400; location = "Bar"},/obj/structure/plasticflaps{opacity = 1},/obj/effect/decal/warning_stripes/yellow/hollow,/turf/simulated/floor,/area/crew_quarters/bar) +"aNx" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/security/brig) "aNy" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aNz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aNA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aNB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) -"aNC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/wall,/area) +"aNC" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable,/obj/structure/sign/securearea,/turf/simulated/floor/plating,/area/security/brig) "aND" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/maintenance{name = "Kitchen Maintenance"; req_access_txt = "28"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/crew_quarters/kitchen) -"aNE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/navbeacon{codes_txt = "delivery;dir=2"; freq = 1400; location = "Kitchen"},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/crew_quarters/kitchen) +"aNE" = (/obj/structure/table,/obj/machinery/door/firedoor,/obj/machinery/door/window/brigdoor{dir = 2; name = "Secure Door"; req_access_txt = "63"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor,/area/security/brig) "aNF" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aNG" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/power/apc{dir = 2; name = "Bar Maintenance APC"; pixel_y = -24},/obj/structure/cable,/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aNH" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) @@ -2067,7 +2067,7 @@ "aNM" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aNN" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aNO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) -"aNP" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/wall,/area) +"aNP" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/security/prison/cell_block/C) "aNQ" = (/obj/structure/filingcabinet,/turf/simulated/floor/wood,/area/library) "aNR" = (/turf/simulated/floor/wood,/area/library) "aNS" = (/obj/structure/stool/bed/chair/office/dark,/obj/machinery/camera{c_tag = "Library North"; dir = 2; network = list("SS13")},/turf/simulated/floor/wood,/area/library) @@ -2080,7 +2080,7 @@ "aNZ" = (/obj/effect/landmark/start{name = "Chaplain"},/obj/structure/stool/bed/chair,/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) "aOa" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = -2; pixel_y = 5},/obj/item/weapon/storage/fancy/crayons,/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) "aOb" = (/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) -"aOc" = (/obj/structure/closet/coffin,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) +"aOc" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/wall/r_wall,/area/maintenance/fsmaint) "aOd" = (/obj/machinery/driver_button{id = "chapelgun"; name = "Chapel Mass Driver"; pixel_x = 25},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) "aOe" = (/turf/simulated/wall,/area/chapel/main) "aOf" = (/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/power/apc{dir = 8; name = "Escape Podbay APC"; pixel_x = -25},/turf/simulated/floor,/area/escapepodbay) @@ -2133,24 +2133,24 @@ "aPa" = (/turf/simulated/floor{dir = 4; icon_state = "bluecorner"},/area/hallway/primary/central/north) "aPb" = (/obj/machinery/power/apc{cell_type = 5000; dir = 1; name = "Central Hall North APC"; pixel_y = 24},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/item/flag/nt,/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/hallway/primary/central/north) "aPc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 5; icon_state = "blue"},/area/hallway/primary/central/north) -"aPd" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area) -"aPe" = (/obj/machinery/vending/cola,/turf/simulated/floor{icon_state = "dark"},/area/hallway/primary/central) +"aPd" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/security/prison/cell_block/C) +"aPe" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/wall/r_wall,/area/maintenance/fsmaint) "aPf" = (/turf/simulated/floor{dir = 8; icon_state = "neutral"},/area/hallway/primary/central/ne) "aPg" = (/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor{icon_state = "neutral"; dir = 4},/area/hallway/primary/central/ne) "aPh" = (/obj/machinery/camera{c_tag = "Dormitories Toilets"; dir = 1; network = list("SS13")},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aPi" = (/obj/machinery/light/small,/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aPj" = (/turf/simulated/wall,/area/crew_quarters/bar) "aPk" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock{name = "Bar Office"; req_access_txt = "25"},/turf/simulated/floor,/area/crew_quarters/bar) -"aPl" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/wall,/area) +"aPl" = (/turf/simulated/wall,/area/crew_quarters/mrchangs) "aPm" = (/obj/machinery/door/airlock/maintenance{name = "Bar Maintenance"; req_access_txt = "12"},/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aPn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/sink/kitchen{pixel_y = 28},/turf/simulated/floor{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) "aPo" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) "aPp" = (/obj/machinery/light/small{dir = 1},/obj/structure/closet/crate{desc = "It's a storage unit for kitchen clothes and equipment."; name = "Kitchen Crate"},/obj/item/clothing/head/chefhat,/obj/item/clothing/under/rank/chef,/obj/item/weapon/storage/box/mousetraps{pixel_x = 5; pixel_y = 5},/obj/item/weapon/storage/box/mousetraps,/obj/item/clothing/under/waiter,/obj/item/clothing/under/waiter,/obj/item/clothing/under/sundress,/turf/simulated/floor{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) "aPq" = (/obj/machinery/camera{c_tag = "Kitchen Freezer"; network = list("SS13")},/obj/machinery/chem_master/condimaster{name = "CondiMaster Neo"; pixel_x = -5},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) "aPr" = (/obj/machinery/door/window/southleft{base_state = "left"; dir = 2; icon_state = "left"; name = "Kitchen Delivery"; req_access_txt = "28"},/obj/effect/decal/warning_stripes/yellow,/turf/simulated/floor{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) -"aPs" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=2"; freq = 1400; location = "Hydroponics"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/hydroponics) -"aPt" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area) -"aPu" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/maintenance{name = "Hydroponics Maintenance"; req_access_txt = "35"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) +"aPs" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/wall,/area/crew_quarters/mrchangs) +"aPt" = (/turf/simulated/wall,/area/civilian/barber) +"aPu" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/civilian/barber) "aPv" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aPw" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/library) "aPx" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/turf/simulated/floor/wood,/area/library) @@ -2158,7 +2158,7 @@ "aPz" = (/obj/structure/table/woodentable,/obj/structure/disposalpipe/segment,/turf/simulated/floor/wood,/area/library) "aPA" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/turf/simulated/floor/wood,/area/library) "aPB" = (/obj/machinery/newscaster{pixel_x = 30},/turf/simulated/floor/wood,/area/library) -"aPC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/wall,/area) +"aPC" = (/turf/simulated/wall/r_wall,/area/civilian/barber) "aPD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor{icon_state = "dark"},/area/chapel/office) "aPE" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/crema_switch{pixel_x = 25},/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/chapel/office) "aPF" = (/obj/structure/table,/obj/item/device/eftpos,/turf/simulated/floor,/area/security/main) @@ -2194,10 +2194,10 @@ "aQj" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable{d2 = 4; icon_state = "0-4"},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable,/turf/simulated/floor/plating,/area/hallway/primary/port) "aQk" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/hallway/primary/port) "aQl" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/fpmaint) -"aQm" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/command{name = "Gateway Access"; req_access_txt = "62"},/turf/simulated/floor,/area/hallway/primary/port) +"aQm" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/command{name = "Gateway Access"; req_access_txt = "62"},/turf/simulated/floor,/area/gateway) "aQn" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/poddoor/shutters{dir = 2; id = "stationawaygate"; name = "Gateway Access Shutters"},/turf/simulated/floor,/area/gateway) "aQo" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/poddoor/shutters{dir = 2; id = "stationawaygate"; name = "Gateway Access Shutters"},/turf/simulated/floor,/area/gateway) -"aQp" = (/obj/structure/sign/securearea,/turf/simulated/wall/r_wall,/area/hallway/primary/central/nw) +"aQp" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/civilian/barber) "aQq" = (/turf/simulated/wall/r_wall,/area/hallway/primary/central/nw) "aQr" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/fpmaint) "aQs" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable,/turf/simulated/floor/plating,/area/ai_monitored/storage/eva) @@ -2209,9 +2209,9 @@ "aQy" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/hallway/primary/central/north) "aQz" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor,/area/hallway/primary/central/north) "aQA" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor{icon_state = "blue"; dir = 4},/area/hallway/primary/central/north) -"aQB" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area) -"aQC" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area) -"aQD" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area) +"aQB" = (/turf/simulated/wall,/area/clownoffice) +"aQC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/wall/r_wall,/area/security/prison/cell_block/B) +"aQD" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/turf/simulated/wall/r_wall,/area/security/prison/cell_block/B) "aQE" = (/obj/machinery/vending/snack,/turf/simulated/floor{icon_state = "dark"},/area/hallway/primary/central) "aQF" = (/turf/simulated/floor{icon_state = "neutral"; dir = 4},/area/hallway/primary/central/ne) "aQG" = (/obj/machinery/light{dir = 1},/obj/machinery/vending/boozeomat,/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) @@ -2232,9 +2232,9 @@ "aQV" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/turf/simulated/floor/grass,/area/hydroponics) "aQW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor/grass,/area/hydroponics) "aQX" = (/obj/item/device/radio/intercom{pixel_y = 25},/obj/machinery/portable_atmospherics/hydroponics/soil,/turf/simulated/floor/grass,/area/hydroponics) -"aQY" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics) -"aQZ" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/structure/closet/crate/hydroponics,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/screwdriver,/obj/item/weapon/shovel/spade,/obj/item/weapon/wrench,/obj/item/weapon/wrench,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics) -"aRa" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics) +"aQY" = (/obj/structure/table,/obj/item/weapon/watertank,/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics) +"aQZ" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics) +"aRa" = (/obj/structure/closet/crate/hydroponics,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/screwdriver,/obj/item/weapon/shovel/spade,/obj/item/weapon/wrench,/obj/item/weapon/wrench,/obj/item/weapon/reagent_containers/glass/bucket,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics) "aRb" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/closet/secure_closet/hydroponics,/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics) "aRc" = (/obj/item/device/radio/intercom{pixel_y = 25},/obj/structure/closet/secure_closet/hydroponics,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics) "aRd" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/obj/structure/closet/secure_closet/hydroponics,/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics) @@ -2242,7 +2242,7 @@ "aRf" = (/obj/machinery/power/apc{dir = 1; name = "Hydroponics APC"; pixel_y = 24},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/table,/obj/machinery/reagentgrinder,/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics) "aRg" = (/obj/machinery/chem_master,/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics) "aRh" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) -"aRi" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/wall,/area) +"aRi" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/security/prison/cell_block/B) "aRj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/light{dir = 8},/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/library) "aRk" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/wood,/area/library) "aRl" = (/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/library) @@ -2318,7 +2318,7 @@ "aSD" = (/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor,/area/hallway/primary/central/ne) "aSE" = (/turf/simulated/floor,/area/hallway/primary/central/ne) "aSF" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 4},/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) -"aSG" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/table/reinforced,/obj/item/weapon/packageWrap,/obj/item/weapon/pen/blue{pixel_x = 0; pixel_y = 4},/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/structure/disposalpipe/segment{dir = 4},/obj/item/weapon/book/manual/barman_recipes,/obj/item/clothing/suit/jacket,/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) +"aSG" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/table/reinforced,/obj/item/stack/packageWrap,/obj/item/weapon/pen/blue{pixel_x = 0; pixel_y = 4},/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/structure/disposalpipe/segment{dir = 4},/obj/item/weapon/book/manual/barman_recipes,/obj/item/clothing/suit/jacket,/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) "aSH" = (/obj/structure/disposalpipe/segment{dir = 4},/mob/living/carbon/monkey{tag = "icon-punpun1"; name = "Pun Pun"; icon_state = "punpun1"},/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) "aSI" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) "aSJ" = (/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) @@ -2337,7 +2337,7 @@ "aSW" = (/turf/simulated/floor{dir = 2; icon_state = "asteroid"; tag = "icon-asteroid (NORTH)"},/turf/simulated/floor{tag = "icon-siding2 (NORTH)"; icon_state = "siding2"; dir = 1},/turf/simulated/floor{tag = "icon-siding1 (NORTH)"; icon_state = "siding1"; dir = 1},/area/hydroponics) "aSX" = (/obj/machinery/door/window/eastright{base_state = "left"; dir = 8; icon_state = "left"; name = "Hydroponics Pasture"; req_access_txt = "35"},/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics) "aSY" = (/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics) -"aSZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics) +"aSZ" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics) "aTa" = (/obj/structure/extinguisher_cabinet{pixel_x = -5; pixel_y = -31},/obj/machinery/light,/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics) "aTb" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics) "aTc" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics) @@ -2423,7 +2423,7 @@ "aUE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/grass,/area/hydroponics) "aUF" = (/mob/living/simple_animal/cow{name = "Betsy"},/turf/simulated/floor/grass,/area/hydroponics) "aUG" = (/obj/structure/flora/ausbushes/sparsegrass,/turf/simulated/floor/grass,/area/hydroponics) -"aUH" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area) +"aUH" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/security/prison/cell_block/A) "aUI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass{name = "Hydroponics"; req_access_txt = "35"},/turf/simulated/floor,/area/hydroponics) "aUJ" = (/obj/machinery/bookbinder{pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/wood,/area/library) "aUK" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/wood,/area/library) @@ -2544,18 +2544,18 @@ "aWV" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atm{pixel_x = 24},/turf/simulated/floor,/area/hallway/primary/port) "aWW" = (/turf/simulated/wall,/area/hallway/primary/central/nw) "aWX" = (/turf/simulated/floor{tag = "icon-stage_stairs"; icon_state = "stage_stairs"},/area/hallway/primary/central/nw) -"aWY" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area) -"aWZ" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area) -"aXa" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area) -"aXb" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/status_display{density = 0; layer = 4},/turf/simulated/floor/plating,/area) -"aXc" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area) -"aXd" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/window/reinforced/tinted,/turf/simulated/floor/plating,/area) -"aXe" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area) -"aXf" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/status_display{density = 0; layer = 4},/turf/simulated/floor/plating,/area) -"aXg" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating,/area) -"aXh" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area) -"aXi" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area) -"aXj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area) +"aWY" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/turf/simulated/wall/r_wall,/area/security/prison/cell_block/A) +"aWZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/wall/r_wall,/area/security/prison/cell_block/A) +"aXa" = (/turf/simulated/wall/r_wall,/area/security/prison/cell_block/C) +"aXb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/wall/r_wall,/area/security/detectives_office) +"aXc" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall/r_wall,/area/security/detectives_office) +"aXd" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/turf/simulated/wall,/area/civilian/barber) +"aXe" = (/turf/simulated/wall/r_wall,/area/security/detectives_office) +"aXf" = (/turf/simulated/wall,/area/hallway/primary/fore) +"aXg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/mimeoffice) +"aXh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/mimeoffice) +"aXi" = (/turf/simulated/wall,/area/magistrateoffice) +"aXj" = (/turf/simulated/wall,/area/lawoffice) "aXk" = (/turf/simulated/floor{tag = "icon-stage_stairs"; icon_state = "stage_stairs"},/area/hallway/primary/central/ne) "aXl" = (/obj/machinery/computer/security/telescreen/entertainment{pixel_x = -32},/obj/structure/stool{pixel_y = 8},/turf/simulated/floor/wood,/area/crew_quarters/bar) "aXm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/stool{pixel_y = 8},/turf/simulated/floor/wood,/area/crew_quarters/bar) @@ -2570,8 +2570,8 @@ "aXv" = (/obj/structure/sink/kitchen{pixel_y = 28},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) "aXw" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) "aXx" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass{name = "Hydroponics Pasture"; req_access_txt = "28"},/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) -"aXy" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area) -"aXz" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area) +"aXy" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area/hallway/primary/fore) +"aXz" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/hallway/primary/fore) "aXA" = (/obj/machinery/floodlight,/obj/machinery/light{dir = 8},/turf/simulated/floor{icon_state = "dark"},/area/hydroponics) "aXB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor{dir = 9; icon_state = "green"},/area/hydroponics) "aXC" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "green"},/area/hydroponics) @@ -2638,7 +2638,7 @@ "aYL" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass{name = "Auxiliary Tool Storage"; req_access_txt = "12"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/storage/tools) "aYM" = (/turf/simulated/wall,/area/storage/tools) "aYN" = (/turf/simulated/floor{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central/nw) -"aYO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area) +"aYO" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/wall,/area/hallway/primary/fore) "aYP" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/secure/briefcase,/obj/item/weapon/storage/box/PDAs{pixel_x = 4; pixel_y = 4},/obj/item/weapon/storage/box/ids,/turf/simulated/floor,/area/bridge) "aYQ" = (/obj/machinery/computer/atmos_alert,/turf/simulated/floor{dir = 10; icon_state = "yellow"},/area/bridge) "aYR" = (/obj/machinery/computer/station_alert,/turf/simulated/floor{dir = 0; icon_state = "yellow"},/area/bridge) @@ -2737,7 +2737,7 @@ "baG" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) "baH" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) "baI" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) -"baJ" = (/obj/machinery/smartfridge,/turf/simulated/wall,/area/crew_quarters/kitchen) +"baJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/civilian/barber) "baK" = (/turf/simulated/floor{dir = 8; icon_state = "vault"; tag = "icon-vault (WEST)"},/area/hydroponics) "baL" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/turf/simulated/floor{icon_state = "green"; dir = 8},/area/hydroponics) "baM" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor{icon_state = "green"; dir = 4},/area/hydroponics) @@ -2764,7 +2764,7 @@ "bbh" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/turf/simulated/floor,/area/hallway/secondary/entry) "bbi" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/status_display{pixel_x = 32},/turf/simulated/floor,/area/hallway/secondary/entry) "bbj" = (/turf/simulated/wall,/area/security/vacantoffice) -"bbk" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/hallway/secondary/entry) +"bbk" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/wall,/area/mimeoffice) "bbl" = (/turf/simulated/floor/plating,/area/maintenance/port) "bbm" = (/obj/effect/decal/cleanable/generic,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/port) "bbn" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/closet/wardrobe/white,/turf/simulated/floor,/area/crew_quarters/locker) @@ -2788,7 +2788,7 @@ "bbF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/storage/tools) "bbG" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/turf/simulated/floor{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central/nw) "bbH" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor,/area/hallway/primary/central/nw) -"bbI" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area) +"bbI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/crew_quarters/sleep) "bbJ" = (/obj/machinery/computer/prisoner{req_access = null; req_access_txt = "2"},/turf/simulated/floor{dir = 10; icon_state = "red"},/area/bridge) "bbK" = (/obj/machinery/computer/security{network = list("SS13","Research Outpost","Mining Outpost","Telecomms")},/obj/machinery/camera{c_tag = "Bridge West"; dir = 2; network = list("SS13")},/turf/simulated/floor{dir = 0; icon_state = "red"},/area/bridge) "bbL" = (/obj/machinery/computer/secure_data,/turf/simulated/floor{dir = 6; icon_state = "red"},/area/bridge) @@ -2803,7 +2803,7 @@ "bbU" = (/obj/machinery/computer/shuttle_control/research{req_access = null; req_access_txt = "65"},/turf/simulated/floor{dir = 10; icon_state = "brown"},/area/bridge) "bbV" = (/obj/machinery/camera{c_tag = "Bridge East"; dir = 2; network = list("SS13")},/obj/machinery/computer/supplycomp,/obj/machinery/computer/security/telescreen/entertainment{pixel_x = 0; pixel_y = 32},/turf/simulated/floor{dir = 2; icon_state = "brown"},/area/bridge) "bbW" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/computer/shuttle_control/engineering{req_access = null; req_one_access_txt = "10;24"},/turf/simulated/floor{dir = 6; icon_state = "brown"},/area/bridge) -"bbX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area) +"bbX" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/crew_quarters/sleep) "bbY" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/camera{c_tag = "Bar West"; dir = 4; network = list("SS13")},/turf/simulated/floor/wood,/area/crew_quarters/bar) "bbZ" = (/obj/structure/disposalpipe/segment,/obj/structure/table/woodentable,/obj/item/device/taperecorder{pixel_y = 0},/turf/simulated/floor/wood,/area/crew_quarters/bar) "bca" = (/obj/structure/table/woodentable,/obj/item/weapon/dice/d20,/turf/simulated/floor/wood,/area/crew_quarters/bar) @@ -2816,7 +2816,7 @@ "bch" = (/obj/structure/table,/obj/item/weapon/kitchen/rollingpin,/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) "bci" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/hologram/holopad,/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) "bcj" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) -"bck" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/window/eastleft{name = "Hydroponics Desk"; req_access_txt = "35"},/obj/machinery/door/window/northleft{dir = 8; icon_state = "left"; name = "Kitchen Desk"; req_access_txt = "28"},/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/crew_quarters/kitchen) +"bck" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/crew_quarters/fitness) "bcl" = (/turf/simulated/floor{icon_state = "green"; dir = 8},/area/hydroponics) "bcm" = (/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/hydroponics) "bcn" = (/turf/simulated/floor{icon_state = "green"; dir = 4},/area/hydroponics) @@ -2836,10 +2836,10 @@ "bcB" = (/obj/machinery/vending/coffee,/turf/simulated/floor{dir = 8; icon_state = "escape"},/area/hallway/secondary/exit) "bcC" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/obj/effect/decal/warning_stripes/southeastcorner,/obj/effect/decal/warning_stripes/northeastcorner,/turf/simulated/floor,/area/hallway/secondary/exit) "bcD" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "escape_dock_north_airlock"; name = "interior access button"; pixel_x = 0; pixel_y = -25; req_access_txt = "13"},/obj/effect/decal/warning_stripes/north,/obj/effect/decal/warning_stripes/south,/turf/simulated/floor,/area/hallway/secondary/exit) -"bcE" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "escape_dock_north_inner"; locked = 1; name = "Escape Airlock"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/hallway/secondary/exit) +"bcE" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/obj/machinery/door/airlock/external{aiControlDisabled = 1; frequency = 1379; hackProof = 1; icon_state = "door_locked"; id_tag = "escape_dock_north_inner"; locked = 1; name = "Escape Airlock"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/hallway/secondary/exit) "bcF" = (/obj/machinery/light/small,/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1379; id_tag = "escape_dock_north_pump"},/obj/machinery/embedded_controller/radio/airlock/docking_port_multi{id_tag = "escape_dock_north_airlock"; master_tag = "escape_dock"; pixel_y = 30; req_one_access_txt = "13"; tag_airpump = "escape_dock_north_pump"; tag_chamber_sensor = "escape_dock_north_sensor"; tag_exterior_door = "escape_dock_north_outer"; tag_interior_door = "escape_dock_north_inner"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "escape_dock_north_sensor"; pixel_x = -8; pixel_y = 30},/turf/simulated/floor/plating,/area/hallway/secondary/exit) "bcG" = (/turf/simulated/floor/plating,/area/hallway/secondary/exit) -"bcH" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "escape_dock_north_outer"; locked = 1; name = "Escape Airlock"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/hallway/secondary/exit) +"bcH" = (/obj/machinery/door/airlock/external{aiControlDisabled = 1; frequency = 1379; hackProof = 1; icon_state = "door_locked"; id_tag = "escape_dock_north_outer"; locked = 1; name = "Escape Airlock"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/hallway/secondary/exit) "bcI" = (/turf/space,/area/shuttle/transport1/station) "bcJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry) "bcK" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/camera{c_tag = "Arrivals Auxiliary Docking North"; dir = 8; network = list("SS13")},/turf/simulated/floor,/area/hallway/secondary/entry) @@ -2865,7 +2865,7 @@ "bde" = (/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/storage/tools) "bdf" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/hallway/primary/central/nw) "bdg" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 32},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{dir = 5; icon_state = "blue"},/area/hallway/primary/central/nw) -"bdh" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/plating,/area) +"bdh" = (/obj/machinery/lapvend,/turf/simulated/floor,/area/quartermaster/office) "bdi" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/sign/securearea{pixel_x = 32; pixel_y = 0},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/bridge) "bdj" = (/turf/simulated/floor{icon_state = "redcorner"; dir = 1},/area/bridge) "bdk" = (/turf/simulated/floor{icon_state = "redcorner"; dir = 4},/area/bridge) @@ -2888,7 +2888,7 @@ "bdB" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/condiment/saltshaker{pixel_x = -2; pixel_y = 4},/obj/item/weapon/reagent_containers/food/condiment/peppermill{pixel_x = 2; pixel_y = 6},/turf/simulated/floor/wood,/area/crew_quarters/bar) "bdC" = (/obj/structure/closet/secure_closet/freezer/kitchen,/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) "bdD" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/table,/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) -"bdE" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/condiment/enzyme{layer = 5},/obj/item/weapon/packageWrap,/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) +"bdE" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/condiment/enzyme{layer = 5},/obj/item/stack/packageWrap,/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) "bdF" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/obj/item/weapon/reagent_containers/glass/beaker{pixel_x = 5},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) "bdG" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/condiment/saltshaker{pixel_x = -3; pixel_y = 0},/obj/item/weapon/reagent_containers/food/condiment/peppermill{pixel_x = 3},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) "bdH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) @@ -2962,7 +2962,7 @@ "beX" = (/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/bridge) "beY" = (/obj/machinery/camera{c_tag = "Bridge Central"; dir = 1; network = list("SS13")},/obj/machinery/requests_console{announcementConsole = 1; department = "Bridge"; departmentType = 5; name = "Bridge RC"; pixel_y = -30},/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/bridge) "beZ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/bridge) -"bfa" = (/obj/machinery/turretid{control_area = "\improper AI Upload Chamber"; name = "AI Upload Turret Control"; pixel_x = 0; pixel_y = -24; req_access = list(75)},/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/bridge) +"bfa" = (/obj/machinery/turretid/stun{control_area = "\improper AI Upload Chamber"; name = "AI Upload Turret Control"; pixel_x = 0; pixel_y = -24; req_access = list(75)},/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/bridge) "bfb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/bridge) "bfc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/newscaster{pixel_y = -32},/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/bridge) "bfd" = (/obj/machinery/power/apc{cell_type = 5000; dir = 2; name = "Bridge APC"; pixel_y = -24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/light,/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/bridge) @@ -3036,20 +3036,20 @@ "bgt" = (/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/hallway/primary/central/nw) "bgu" = (/obj/machinery/camera{c_tag = "Bridge West Entrance"; dir = 1; network = list("SS13")},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/hallway/primary/central/nw) "bgv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "blue"; dir = 6},/area/hallway/primary/central/nw) -"bgw" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area) +"bgw" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/crew_quarters/fitness) "bgx" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/bridge) "bgy" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/structure/closet/emcloset,/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/bridge) "bgz" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/bridge) "bgA" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor{icon_state = "blue"; dir = 6},/area/bridge) "bgB" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/highsecurity{name = "AI Upload Access"; req_access_txt = "16"},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload) -"bgC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/wall/r_wall,/area) -"bgD" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/turf/simulated/wall/r_wall,/area) -"bgE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/wall/r_wall,/area) +"bgC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/crew_quarters/mrchangs) +"bgD" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/turf/simulated/wall,/area/crew_quarters/mrchangs) +"bgE" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area/crew_quarters/mrchangs) "bgF" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/structure/filingcabinet/filingcabinet,/turf/simulated/floor{icon_state = "blue"; dir = 10},/area/bridge) "bgG" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/bridge) "bgH" = (/obj/structure/closet/emcloset,/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/bridge) "bgI" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/bridge) -"bgJ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable,/turf/simulated/floor/plating,/area) +"bgJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/civilian/barber) "bgK" = (/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "blue"; dir = 10},/area/hallway/primary/central/ne) "bgL" = (/obj/machinery/power/apc{dir = 2; name = "Central Hall APC"; pixel_y = -24},/obj/structure/cable,/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/hallway/primary/central/ne) "bgM" = (/obj/machinery/light,/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/hallway/primary/central/ne) @@ -3103,7 +3103,7 @@ "bhI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/hallway/primary/central/nw) "bhJ" = (/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "bluecorner"},/area/hallway/primary/central/nw) "bhK" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/command{name = "Conference Room"; req_access = null; req_access_txt = "19"},/turf/simulated/floor/wood,/area/bridge/meeting_room) -"bhL" = (/obj/machinery/turret,/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload) +"bhL" = (/obj/machinery/porta_turret,/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload) "bhM" = (/obj/machinery/ai_status_display{pixel_y = 32},/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) "bhN" = (/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) "bhO" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload) @@ -3161,7 +3161,7 @@ "biO" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage) "biP" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage) "biQ" = (/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage) -"biR" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/module/power_control,/obj/item/weapon/cell{maxcharge = 2000},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage) +"biR" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/module/power_control,/obj/item/weapon/stock_parts/cell{maxcharge = 2000},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage) "biS" = (/obj/machinery/conveyor{dir = 1; id = "packageSort1"},/turf/simulated/floor/plating,/area/quartermaster/office) "biT" = (/obj/structure/stool,/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/quartermaster/office) "biU" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/quartermaster/office) @@ -3193,18 +3193,18 @@ "bju" = (/obj/structure/flora/kirbyplants,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/wood,/area/crew_quarters/captain) "bjv" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/central/ne) "bjw" = (/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/hallway/primary/central/ne) -"bjx" = (/obj/structure/sign/directions/evac{dir = 4},/obj/structure/sign/directions/medical{dir = 4; pixel_y = 7},/obj/structure/sign/directions/science{dir = 4},/turf/simulated/wall,/area) +"bjx" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/turf/simulated/wall,/area/civilian/barber) "bjy" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass{name = "Diner"},/turf/simulated/floor,/area/crew_quarters/bar) -"bjz" = (/obj/structure/sign/double/barsign,/turf/simulated/wall,/area) +"bjz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/wall,/area/civilian/barber) "bjA" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{dir = 1; icon_state = "whitecorner"},/area/hallway/primary/starboard/west) "bjB" = (/turf/simulated/floor{dir = 1; icon_state = "whitecorner"},/area/hallway/primary/starboard/west) "bjC" = (/obj/machinery/camera{c_tag = "Starboard Primary Hallway 2"; dir = 2; network = list("SS13")},/turf/simulated/floor{dir = 1; icon_state = "whitecorner"},/area/hallway/primary/starboard/west) "bjD" = (/obj/structure/flora/kirbyplants,/turf/simulated/floor{dir = 1; icon_state = "whitecorner"},/area/hallway/primary/starboard/west) -"bjE" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area) +"bjE" = (/turf/simulated/wall,/area/crew_quarters/fitness) "bjF" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor/border_only,/obj/machinery/door/window/westright{dir = 1; name = "Hydroponics Desk"; req_access_txt = "35"},/turf/simulated/floor,/area/hydroponics) "bjG" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass{name = "Hydroponics"; req_access_txt = "35"},/turf/simulated/floor,/area/hydroponics) "bjH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/hallway/primary/starboard/east) -"bjI" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area) +"bjI" = (/turf/simulated/wall/r_wall,/area/crew_quarters/fitness) "bjJ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor{dir = 8; icon_state = "escape"},/area/hallway/secondary/exit) "bjK" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor,/area/hallway/secondary/exit) "bjL" = (/obj/structure/grille,/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/hallway/secondary/exit) @@ -3228,11 +3228,11 @@ "bkd" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/quartermaster/office) "bke" = (/turf/simulated/floor,/area/quartermaster/office) "bkf" = (/obj/item/weapon/storage/box,/obj/structure/table,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = 20},/turf/simulated/floor{icon_state = "arrival"; dir = 1},/area/quartermaster/office) -"bkg" = (/obj/structure/table,/obj/item/weapon/wrapping_paper,/obj/item/weapon/wrapping_paper,/obj/machinery/requests_console{department = "Cargo Bay"; departmentType = 2; pixel_y = 30},/turf/simulated/floor{icon_state = "arrival"; dir = 1},/area/quartermaster/office) -"bkh" = (/obj/structure/table,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/turf/simulated/floor{icon_state = "arrival"; dir = 5},/area/quartermaster/office) +"bkg" = (/obj/structure/table,/obj/machinery/requests_console{department = "Cargo Bay"; departmentType = 2; pixel_y = 30},/turf/simulated/floor{icon_state = "arrival"; dir = 1},/area/quartermaster/office) +"bkh" = (/obj/structure/table,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/turf/simulated/floor{icon_state = "arrival"; dir = 5},/area/quartermaster/office) "bki" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/floor{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central/west) "bkj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/hallway/primary/central/west) -"bkk" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "heads_meeting"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) +"bkk" = (/turf/simulated/wall,/area/mimeoffice) "bkl" = (/obj/machinery/recharger{pixel_y = 4},/obj/structure/table,/turf/simulated/floor/wood,/area/bridge/meeting_room) "bkm" = (/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor/wood,/area/bridge/meeting_room) "bkn" = (/turf/simulated/floor/carpet,/area/bridge/meeting_room) @@ -3288,9 +3288,9 @@ "bll" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor,/area/hallway/secondary/exit) "blm" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 8},/obj/effect/decal/warning_stripes/southeastcorner,/obj/effect/decal/warning_stripes/northeastcorner,/turf/simulated/floor,/area/hallway/secondary/exit) "bln" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "escape_dock_south_airlock"; name = "interior access button"; pixel_x = 0; pixel_y = 25; req_access_txt = "13"},/obj/effect/decal/warning_stripes/north,/obj/effect/decal/warning_stripes/south,/turf/simulated/floor,/area/hallway/secondary/exit) -"blo" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "escape_dock_south_inner"; locked = 1; name = "Escape Airlock"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/hallway/secondary/exit) +"blo" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/obj/machinery/door/airlock/external{aiControlDisabled = 1; frequency = 1379; hackProof = 1; icon_state = "door_locked"; id_tag = "escape_dock_south_inner"; locked = 1; name = "Escape Airlock"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/hallway/secondary/exit) "blp" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1379; id_tag = "escape_dock_south_pump"},/obj/machinery/embedded_controller/radio/airlock/docking_port_multi{id_tag = "escape_dock_south_airlock"; master_tag = "escape_dock"; pixel_y = -30; req_one_access_txt = "13"; tag_airpump = "escape_dock_south_pump"; tag_chamber_sensor = "escape_dock_south_sensor"; tag_exterior_door = "escape_dock_south_outer"; tag_interior_door = "escape_dock_south_inner"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "escape_dock_south_sensor"; pixel_x = -8; pixel_y = -30},/turf/simulated/floor/plating,/area/hallway/secondary/exit) -"blq" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "escape_dock_south_outer"; locked = 1; name = "Escape Airlock"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/hallway/secondary/exit) +"blq" = (/obj/machinery/door/airlock/external{aiControlDisabled = 1; frequency = 1379; hackProof = 1; icon_state = "door_locked"; id_tag = "escape_dock_south_outer"; locked = 1; name = "Escape Airlock"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/hallway/secondary/exit) "blr" = (/turf/space,/area/shuttle/specops/station) "bls" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry) "blt" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 8},/turf/simulated/floor{icon_state = "warningcorner"; dir = 1},/area/hallway/secondary/entry) @@ -3316,7 +3316,7 @@ "blN" = (/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/quartermaster/office) "blO" = (/obj/structure/table,/obj/item/device/destTagger{pixel_x = 4; pixel_y = 3},/obj/item/device/destTagger{pixel_x = 4; pixel_y = 3},/obj/machinery/light{dir = 4},/obj/item/weapon/rcs,/turf/simulated/floor{icon_state = "arrival"; dir = 4},/area/quartermaster/office) "blP" = (/obj/machinery/atm{pixel_x = -32},/turf/simulated/floor{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central/west) -"blQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "heads_meeting"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) +"blQ" = (/turf/simulated/wall,/area/crew_quarters/sleep) "blR" = (/obj/item/weapon/hand_labeler,/obj/item/device/assembly/timer,/obj/structure/table,/turf/simulated/floor/wood,/area/bridge/meeting_room) "blS" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/wood,/area/bridge/meeting_room) "blT" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/turf/simulated/floor/carpet,/area/bridge/meeting_room) @@ -3324,10 +3324,10 @@ "blV" = (/obj/item/weapon/book/manual/security_space_law,/obj/structure/table/woodentable,/turf/simulated/floor/carpet,/area/bridge/meeting_room) "blW" = (/obj/structure/stool/bed/chair/comfy/black{dir = 8},/turf/simulated/floor/carpet,/area/bridge/meeting_room) "blX" = (/obj/machinery/vending/cola,/turf/simulated/floor/wood,/area/bridge/meeting_room) -"blY" = (/obj/machinery/turret{dir = 4},/obj/machinery/alarm{dir = 4; hidden = 1; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload) +"blY" = (/obj/machinery/alarm{dir = 4; hidden = 1; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/porta_turret{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload) "blZ" = (/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/turret_protected/ai_upload) "bma" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) -"bmb" = (/obj/machinery/turret{dir = 8},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload) +"bmb" = (/obj/machinery/porta_turret{dir = 8},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload) "bmc" = (/obj/machinery/computer/arcade,/turf/simulated/floor/wood,/area/crew_quarters/captain) "bmd" = (/obj/structure/table/woodentable,/turf/simulated/floor/carpet,/area/crew_quarters/captain) "bme" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor/wood,/area/crew_quarters/captain) @@ -3362,7 +3362,7 @@ "bmH" = (/obj/machinery/camera{c_tag = "Cargo Delivery Office"; dir = 4; network = list("SS13")},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/telepad_cargo,/turf/simulated/floor{dir = 8; icon_state = "brown"},/area/quartermaster/office) "bmI" = (/obj/structure/filingcabinet/filingcabinet,/turf/simulated/floor{icon_state = "arrival"; dir = 4},/area/quartermaster/office) "bmJ" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central/west) -"bmK" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "heads_meeting"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) +"bmK" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/turf/simulated/wall,/area/mimeoffice) "bmL" = (/obj/item/weapon/storage/fancy/donut_box,/obj/structure/table,/turf/simulated/floor/wood,/area/bridge/meeting_room) "bmM" = (/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/obj/structure/table/woodentable,/turf/simulated/floor/carpet,/area/bridge/meeting_room) "bmN" = (/obj/item/weapon/folder/blue,/obj/structure/table/woodentable,/turf/simulated/floor/carpet,/area/bridge/meeting_room) @@ -3374,7 +3374,7 @@ "bmT" = (/obj/machinery/computer/borgupload,/obj/item/device/radio/intercom{anyai = 1; broadcasting = 0; freerange = 1; frequency = 1447; name = "Private Channel"; pixel_x = 0; pixel_y = -29},/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) "bmU" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/machinery/light,/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload) "bmV" = (/obj/structure/table,/obj/machinery/door/window{base_state = "left"; dir = 8; icon_state = "left"; name = "High-Risk Modules"; req_access_txt = "20"},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/item/weapon/aiModule/supplied/oxygen,/obj/item/weapon/aiModule/zeroth/oneHuman,/obj/item/weapon/aiModule/reset/purge,/obj/item/weapon/aiModule/core/full/antimov,/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) -"bmW" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/wall/r_wall,/area) +"bmW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/magistrateoffice) "bmX" = (/obj/machinery/light{dir = 8},/obj/machinery/photocopier,/turf/simulated/floor/wood,/area/crew_quarters/captain) "bmY" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/wood,/area/crew_quarters/captain) "bmZ" = (/obj/structure/stool/bed/chair,/turf/simulated/floor/wood,/area/crew_quarters/captain) @@ -3447,7 +3447,7 @@ "boo" = (/turf/simulated/floor/wood,/area/bridge/meeting_room) "bop" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/requests_console{announcementConsole = 1; department = "Bridge"; departmentType = 5; name = "Bridge RC"; pixel_y = -30},/turf/simulated/floor/wood,/area/bridge/meeting_room) "boq" = (/obj/machinery/vending/cigarette,/turf/simulated/floor/wood,/area/bridge/meeting_room) -"bor" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/wall/r_wall,/area) +"bor" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/wall,/area/crew_quarters/sleep) "bos" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 10},/obj/item/weapon/pen{pixel_y = 10},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_x = -30; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door_control{id = "captainofficedoor"; name = "Office Door"; normaldoorcontrol = 1; pixel_x = 5; pixel_y = -3; req_access_txt = "20"},/turf/simulated/floor/wood,/area/crew_quarters/captain) "bot" = (/obj/structure/table/woodentable,/obj/item/weapon/folder/blue,/obj/item/weapon/stamp/captain,/turf/simulated/floor/wood,/area/crew_quarters/captain) "bou" = (/obj/structure/table/woodentable,/obj/item/weapon/hand_tele,/turf/simulated/floor/wood,/area/crew_quarters/captain) @@ -3457,8 +3457,8 @@ "boy" = (/obj/structure/table/woodentable,/obj/item/weapon/pinpointer,/obj/item/weapon/disk/nuclear,/obj/item/weapon/storage/secure/safe{pixel_x = 35; pixel_y = 5},/turf/simulated/floor/wood,/area/crew_quarters/captain) "boz" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/central/sw) "boA" = (/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/hallway/primary/central/sw) -"boB" = (/obj/structure/sign/nosmoking_1,/turf/simulated/wall,/area) -"boC" = (/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"},/turf/simulated/wall,/area) +"boB" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "eva_airlock"; name = "exterior access button"; pixel_x = 0; pixel_y = 25; req_access_txt = "13"},/turf/simulated/floor/plating/airless,/area) +"boC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/hallway/primary/fore) "boD" = (/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{tag = "icon-warnwhite (NORTH)"; icon_state = "warnwhite"; dir = 1},/area/medical/reception) "boE" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/door/airlock/medical{name = "Morgue"; req_access_txt = "0"; req_one_access_txt = "6,9"},/turf/simulated/floor,/area/medical/morgue) "boF" = (/obj/machinery/door/airlock{name = "Starboard Emergency Storage"; req_access_txt = "0"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/asmaint) @@ -3520,7 +3520,7 @@ "bpJ" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/beakers,/obj/item/weapon/storage/box/beakers,/obj/item/weapon/reagent_containers/dropper,/obj/machinery/camera{c_tag = "Medbay Chemistry"; network = list("SS13")},/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = 30},/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) "bpK" = (/obj/structure/table/reinforced,/obj/item/stack/sheet/mineral/plasma,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) "bpL" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/table/reinforced,/obj/machinery/reagentgrinder,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) -"bpM" = (/obj/structure/sign/chemistry,/turf/simulated/wall/r_wall,/area) +"bpM" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/wall,/area/crew_quarters/sleep) "bpN" = (/obj/structure/reagent_dispensers/water_cooler,/turf/simulated/floor{tag = "icon-whiteblue (NORTHWEST)"; icon_state = "whiteblue"; dir = 9},/area/medical/reception) "bpO" = (/obj/structure/closet/walllocker/emerglocker/north,/obj/structure/table,/obj/item/weapon/storage/box/cups,/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/reception) "bpP" = (/obj/machinery/camera{c_tag = "Medbay Lobby West"; network = list("SS13")},/obj/structure/stool,/obj/effect/landmark/start{name = "Civilian"},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/reception) @@ -3546,10 +3546,10 @@ "bqj" = (/obj/machinery/computer/rdconsole/robotics,/obj/machinery/alarm{pixel_y = 25},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) "bqk" = (/obj/structure/table,/obj/item/weapon/book/manual/robotics_cyborgs{pixel_x = 2; pixel_y = 5},/obj/item/weapon/storage/belt/utility,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/machinery/requests_console{department = "Robotics"; departmentType = 2; name = "Robotics Requests Console"; pixel_y = 30},/obj/machinery/light{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) "bql" = (/obj/machinery/r_n_d/circuit_imprinter,/obj/item/weapon/reagent_containers/glass/beaker/sulphuric,/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) -"bqm" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "robotics"; name = "Robotics Lab Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) +"bqm" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating/airless,/area) "bqn" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/machinery/door/window/eastright{base_state = "left"; dir = 2; icon_state = "left"; name = "Robotics Desk"; req_access_txt = "29"},/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/obj/item/weapon/folder/white,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "robotics"; name = "Robotics Lab Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/assembly/robotics) "bqo" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{dir = 10; icon_state = "purple"},/area/hallway/primary/starboard/east) -"bqp" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "rdlab"; name = "Research and Development Lab Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) +"bqp" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/mimeoffice) "bqq" = (/obj/structure/table/reinforced,/obj/machinery/door/window/eastright{base_state = "left"; dir = 2; icon_state = "left"; name = "Research and Development Desk"; req_access_txt = "47"},/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "rdlab"; name = "Research and Development Lab Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/toxins/lab) "bqr" = (/obj/machinery/autolathe,/turf/simulated/floor{icon_state = "white"},/area/toxins/lab) "bqs" = (/obj/structure/table,/obj/machinery/recharger{pixel_y = 0},/obj/item/weapon/storage/belt/utility,/obj/item/clothing/gloves/color/latex,/turf/simulated/floor{icon_state = "white"},/area/toxins/lab) @@ -3608,7 +3608,7 @@ "brt" = (/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/reception) "bru" = (/turf/simulated/floor/airless{icon_state = "white"},/area/medical/reception) "brv" = (/obj/structure/stool,/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/medical/reception) -"brw" = (/obj/structure/sign/examroom,/turf/simulated/wall,/area) +"brw" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/magistrateoffice) "brx" = (/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/medical/exam_room) "bry" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/medical/exam_room) "brz" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/medical/exam_room) @@ -3656,8 +3656,8 @@ "bsp" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/port) "bsq" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/port) "bsr" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/port) -"bss" = (/obj/structure/table,/obj/item/clothing/head/soft,/obj/item/weapon/stamp{pixel_x = -3; pixel_y = 3},/obj/item/clothing/head/soft,/turf/simulated/floor,/area/quartermaster/storage) -"bst" = (/obj/structure/table,/obj/item/weapon/hand_labeler,/obj/machinery/requests_console{department = "Cargo Bay"; departmentType = 2; pixel_x = 0; pixel_y = 30},/obj/item/weapon/stamp{pixel_x = -3; pixel_y = 3},/obj/item/weapon/hand_labeler,/turf/simulated/floor,/area/quartermaster/storage) +"bss" = (/obj/structure/table,/obj/item/clothing/head/soft,/obj/item/weapon/stamp/granted{pixel_x = -3; pixel_y = 3},/obj/item/clothing/head/soft,/turf/simulated/floor,/area/quartermaster/storage) +"bst" = (/obj/structure/table,/obj/item/weapon/hand_labeler,/obj/machinery/requests_console{department = "Cargo Bay"; departmentType = 2; pixel_x = 0; pixel_y = 30},/obj/item/weapon/stamp/granted{pixel_x = -3; pixel_y = 3},/obj/item/weapon/hand_labeler,/turf/simulated/floor,/area/quartermaster/storage) "bsu" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = 20},/turf/simulated/floor,/area/quartermaster/storage) "bsv" = (/obj/machinery/camera{c_tag = "Cargo Bay North"},/obj/structure/closet/secure_closet/cargotech,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor,/area/quartermaster/storage) "bsw" = (/obj/structure/closet/secure_closet/cargotech,/turf/simulated/floor,/area/quartermaster/storage) @@ -3709,7 +3709,7 @@ "btq" = (/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/medical/morgue) "btr" = (/obj/structure/morgue{tag = "icon-morgue1 (WEST)"; icon_state = "morgue1"; dir = 8},/obj/machinery/light/small{dir = 4},/turf/simulated/floor,/area/medical/morgue) "bts" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/sortjunction{dir = 2; icon_state = "pipe-j2s"; sortType = 12},/turf/simulated/floor/plating,/area/maintenance/asmaint) -"btt" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area) +"btt" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/wall,/area/magistrateoffice) "btu" = (/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/bluegrid,/area/assembly/chargebay) "btv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/bluegrid,/area/assembly/chargebay) "btw" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/assembly/chargebay) @@ -3719,7 +3719,7 @@ "btA" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) "btB" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) "btC" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/storage/toolbox/electrical{pixel_x = 1; pixel_y = 6},/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/item/clothing/head/welding{pixel_x = -3; pixel_y = 5},/obj/item/clothing/glasses/welding,/obj/structure/disposalpipe/segment{dir = 4},/obj/item/device/radio/headset/headset_sci{pixel_x = -3},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) -"btD" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area) +"btD" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/lawoffice) "btE" = (/obj/structure/closet/emcloset,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{dir = 9; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTHEAST)"},/area/medical/research{name = "Research Division"}) "btF" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/research{name = "Research Division"}) "btG" = (/obj/machinery/camera{c_tag = "Research Access"; dir = 2; network = list("Research","SS13")},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{tag = "icon-warnwhite (NORTHEAST)"; icon_state = "warnwhite"; dir = 5},/area/medical/research{name = "Research Division"}) @@ -3816,7 +3816,7 @@ "bvt" = (/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/toxins/lab) "bvu" = (/obj/machinery/r_n_d/protolathe,/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/toxins/lab) "bvv" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "white"},/area/toxins/lab) -"bvw" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/obj/structure/table,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/pen,/obj/item/weapon/hand_labeler,/turf/simulated/floor{icon_state = "white"},/area/toxins/lab) +"bvw" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/obj/structure/table,/obj/item/stack/packageWrap,/obj/item/weapon/pen,/obj/item/weapon/hand_labeler,/turf/simulated/floor{icon_state = "white"},/area/toxins/lab) "bvx" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/tank/oxygen,/obj/item/weapon/storage/belt/utility,/obj/item/clothing/mask/breath,/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bvy" = (/obj/machinery/airlock_sensor{frequency = 1380; id_tag = "admin_shuttle_dock_sensor"; pixel_x = -30; pixel_y = 8},/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/hallway/secondary/entry) "bvz" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1380; id_tag = "admin_shuttle_dock_pump"},/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/hallway/secondary/entry) @@ -3863,8 +3863,8 @@ "bwo" = (/obj/machinery/chem_dispenser,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) "bwp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) "bwq" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) -"bwr" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/table/reinforced,/obj/item/weapon/packageWrap,/obj/item/device/mass_spectrometer/adv,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) -"bws" = (/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"},/turf/simulated/wall/r_wall,/area) +"bwr" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/table/reinforced,/obj/item/stack/packageWrap,/obj/item/device/mass_spectrometer/adv,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) +"bws" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/wall,/area/magistrateoffice) "bwt" = (/turf/simulated/floor{tag = "icon-whiteblue (SOUTHWEST)"; icon_state = "whiteblue"; dir = 10},/area/medical/reception) "bwu" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/reception) "bwv" = (/obj/structure/table,/obj/item/weapon/reagent_containers/spray/cleaner,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/medical/reception) @@ -3886,19 +3886,19 @@ "bwL" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/medical/morgue) "bwM" = (/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/medical/morgue) "bwN" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/sortjunction{dir = 2; icon_state = "pipe-j2s"; sortType = 13},/turf/simulated/floor/plating,/area/maintenance/asmaint) -"bwO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area) +"bwO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/lawoffice) "bwP" = (/obj/machinery/camera{c_tag = "Research Mech Bay"; dir = 4; network = list("Research","SS13")},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/assembly/chargebay) "bwQ" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/assembly/chargebay) "bwR" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/assembly/chargebay) "bwS" = (/obj/machinery/hologram/holopad,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/assembly/chargebay) -"bwT" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area) +"bwT" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/wall,/area/lawoffice) "bwU" = (/obj/structure/table,/obj/item/stack/sheet/plasteel{amount = 10},/obj/item/stack/cable_coil,/obj/item/device/flash,/obj/item/device/flash,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/assembly/robotics) "bwV" = (/obj/structure/stool,/obj/effect/landmark/start{name = "Roboticist"},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/assembly/robotics) "bwW" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/effect/decal/warning_stripes/yellow,/turf/simulated/floor,/area/assembly/robotics) "bwX" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/effect/decal/warning_stripes/east,/obj/effect/decal/warning_stripes/yellow,/turf/simulated/floor,/area/assembly/robotics) "bwY" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) "bwZ" = (/obj/machinery/hologram/holopad,/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) -"bxa" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/device/radio/intercom{freerange = 0; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) +"bxa" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/obj/item/device/radio/intercom{freerange = 0; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) "bxb" = (/obj/structure/closet/firecloset,/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor{dir = 10; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTHEAST)"},/area/medical/research{name = "Research Division"}) "bxc" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor{dir = 6; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTHEAST)"},/area/medical/research{name = "Research Division"}) "bxd" = (/obj/machinery/light{dir = 8},/obj/machinery/computer/rdconsole/core,/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/toxins/lab) @@ -3930,7 +3930,7 @@ "bxD" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "brown"},/area/quartermaster/office) "bxE" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/quartermaster/office) "bxF" = (/obj/structure/disposalpipe/segment{name = "Sorting Office"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor,/area/quartermaster/office) -"bxG" = (/obj/item/weapon/stamp{pixel_x = -3; pixel_y = 3},/obj/item/weapon/stamp/denied{pixel_x = 4; pixel_y = -2},/obj/structure/table,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/floor,/area/quartermaster/office) +"bxG" = (/obj/item/weapon/stamp/granted{pixel_x = -3; pixel_y = 3},/obj/item/weapon/stamp/denied{pixel_x = 4; pixel_y = -2},/obj/structure/table,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/floor,/area/quartermaster/office) "bxH" = (/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/clipboard,/obj/item/weapon/pen/red{pixel_x = 2; pixel_y = 6},/obj/structure/table,/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1},/turf/simulated/floor,/area/quartermaster/office) "bxI" = (/obj/machinery/computer/ordercomp,/obj/item/device/radio/intercom{broadcasting = 0; name = "Station Intercom (General)"; pixel_y = 20},/turf/simulated/floor,/area/quartermaster/office) "bxJ" = (/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor,/area/quartermaster/office) @@ -3940,7 +3940,7 @@ "bxN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/hallway/primary/central/sw) "bxO" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 27},/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/hallway/primary/central/sw) "bxP" = (/obj/machinery/computer/secure_data,/obj/machinery/flasher_button{id = "hopflash"; pixel_x = 6; pixel_y = 36},/obj/machinery/door_control{id = "hopqueue"; name = "Queue Privacy Shutters Control"; pixel_x = -4; pixel_y = 25; req_access_txt = "28"},/obj/machinery/door_control{id = "hop"; name = "Privacy Shutters Control"; pixel_x = 6; pixel_y = 25; req_access_txt = "28"},/obj/machinery/light_switch{pixel_x = -4; pixel_y = 36},/turf/simulated/floor{dir = 9; icon_state = "blue"},/area/crew_quarters/heads) -"bxQ" = (/obj/structure/table,/obj/machinery/newscaster/security_unit{pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/media/receiver/boombox,/obj/item/weapon/packageWrap,/obj/item/weapon/hand_labeler,/turf/simulated/floor,/area/crew_quarters/heads) +"bxQ" = (/obj/structure/table,/obj/machinery/newscaster/security_unit{pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/media/receiver/boombox,/obj/item/stack/packageWrap,/obj/item/weapon/hand_labeler,/turf/simulated/floor,/area/crew_quarters/heads) "bxR" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/obj/machinery/recharger/wallcharger{pixel_x = 0; pixel_y = 30},/turf/simulated/floor,/area/crew_quarters/heads) "bxS" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/power/apc{dir = 1; name = "Head of Personnel APC"; pixel_y = 24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/photocopier,/turf/simulated/floor,/area/crew_quarters/heads) "bxT" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor,/area/crew_quarters/heads) @@ -3957,10 +3957,10 @@ "bye" = (/obj/machinery/light/small{dir = 8},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/crew_quarters/captain) "byf" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/hallway/primary/central/sw) "byg" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 30},/turf/simulated/floor,/area/hallway/primary/central/sw) -"byh" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area) -"byi" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area) +"byh" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/turf/simulated/wall,/area/lawoffice) +"byi" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/crew_quarters/sleep) "byj" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{id_tag = null; name = "Chemistry Lab"; req_access_txt = "33"},/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) -"byk" = (/obj/structure/sign/chemistry,/turf/simulated/wall,/area) +"byk" = (/turf/simulated/wall,/area/maintenance/abandonedbar) "byl" = (/obj/effect/decal/warning_stripes/yellow/partial,/obj/effect/decal/warning_stripes/arrow,/turf/simulated/floor,/area/medical/reception) "bym" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/effect/decal/warning_stripes/yellow/partial,/obj/effect/decal/warning_stripes/arrow,/turf/simulated/floor,/area/medical/reception) "byn" = (/obj/machinery/door/window/eastright{base_state = "left"; dir = 8; icon_state = "left"; name = "Medical Reception"; req_access_txt = "5"},/turf/simulated/floor,/area/medical/reception) @@ -3972,19 +3972,19 @@ "byt" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/decal/warning_stripes/yellow/partial{dir = 1},/obj/effect/decal/warning_stripes/arrow{dir = 1},/turf/simulated/floor,/area/medical/reception) "byu" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/glass_medical{id_tag = null; name = "Examination Room"; req_access_txt = "5"},/turf/simulated/floor{icon_state = "white"},/area/medical/exam_room) "byv" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area/medical/exam_room) -"byw" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/medical{name = "Morgue"; req_access_txt = "0"; req_one_access_txt = "6,9"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) -"byx" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/wall,/area) +"byw" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/hallway/primary/fore) +"byx" = (/turf/simulated/wall/r_wall,/area/ai_monitored/storage/eva) "byy" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/asmaint) "byz" = (/obj/machinery/mech_bay_recharge_port,/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating,/area/assembly/chargebay) "byA" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/assembly/chargebay) -"byB" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area) +"byB" = (/obj/structure/sign/securearea,/turf/simulated/wall/r_wall,/area/ai_monitored/storage/eva) "byC" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor,/area/assembly/robotics) "byD" = (/turf/simulated/floor,/area/assembly/robotics) "byE" = (/obj/effect/decal/warning_stripes/east,/turf/simulated/floor,/area/assembly/robotics) "byF" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) -"byG" = (/obj/structure/table,/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000; pixel_x = 5; pixel_y = -5},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/item/weapon/crowbar,/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) -"byH" = (/obj/machinery/status_display,/turf/simulated/wall/r_wall,/area) -"byI" = (/obj/structure/sign/securearea,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area) +"byG" = (/obj/structure/table,/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000; pixel_x = 5; pixel_y = -5},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/item/weapon/crowbar,/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) +"byH" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/ai_monitored/storage/eva) +"byI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/ai_monitored/storage/eva) "byJ" = (/obj/machinery/newscaster{pixel_x = -27; pixel_y = 1},/turf/simulated/floor{icon_state = "white"},/area/toxins/lab) "byK" = (/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor{icon_state = "white"},/area/toxins/lab) "byL" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/toxins/lab) @@ -4001,7 +4001,7 @@ "byW" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/storage) "byX" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/storage) "byY" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/storage) -"byZ" = (/obj/machinery/conveyor_switch/oneway{id = "QMLoad2"},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/quartermaster/storage) +"byZ" = (/obj/machinery/conveyor_switch/oneway{id = "QMLoad2"},/turf/simulated/floor,/area/quartermaster/storage) "bza" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/quartermaster/storage) "bzb" = (/turf/simulated/floor{icon_state = "bot"},/area/quartermaster/storage) "bzc" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "browncorner"},/area/quartermaster/office) @@ -4044,7 +4044,7 @@ "bzN" = (/obj/structure/closet/secure_closet/chemical,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor{dir = 5; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/chemistry) "bzO" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/door/airlock/glass_medical{id_tag = "MedbayFoyerPort"; name = "Medbay Entrance Port"; req_access_txt = "5"},/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/medical/medbay2) "bzP" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/door/airlock/glass_medical{id_tag = "MedbayFoyerPort"; name = "Medbay Entrance Port"; req_access_txt = "5"},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/medical/medbay2) -"bzQ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area) +"bzQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "bzR" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/medbay3) "bzS" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/door/airlock/glass_medical{id_tag = "MedbayFoyerStar"; name = "Medbay Entrance Starboard"; req_access_txt = "5"},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/medical/medbay2) "bzT" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/door/airlock/glass_medical{id_tag = "MedbayFoyerStar"; name = "Medbay Entrance Starboard"; req_access_txt = "5"},/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/medical/medbay2) @@ -4073,7 +4073,7 @@ "bAq" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor{icon_state = "bot"},/area/medical/research{name = "Research Division"}) "bAr" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "bot"},/area/medical/research{name = "Research Division"}) "bAs" = (/obj/machinery/door_control{id = "rdlab2"; name = "Research and Development Lab Shutters Control"; pixel_x = -24; pixel_y = -24; req_access_txt = "47"},/turf/simulated/floor{icon_state = "white"},/area/toxins/lab) -"bAt" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor{icon_state = "white"},/area/toxins/lab) +"bAt" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor{icon_state = "white"},/area/toxins/lab) "bAu" = (/obj/structure/table,/obj/item/weapon/storage/belt/utility,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = 0; pixel_y = 0},/obj/item/weapon/storage/toolbox/mechanical{pixel_x = 0; pixel_y = 0},/turf/simulated/floor{icon_state = "white"},/area/toxins/lab) "bAv" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/toxins/lab) "bAw" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/table,/obj/item/stack/cable_coil,/obj/item/stack/cable_coil,/obj/item/weapon/stock_parts/scanning_module{pixel_x = 0; pixel_y = 0},/obj/item/weapon/stock_parts/scanning_module{pixel_x = 2; pixel_y = 3},/obj/machinery/light_switch{pixel_y = -25},/turf/simulated/floor{icon_state = "white"},/area/toxins/lab) @@ -4096,7 +4096,7 @@ "bAN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central/sw) "bAO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor,/area/hallway/primary/central/sw) "bAP" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "redcorner"; dir = 4},/area/hallway/primary/central/sw) -"bAQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area) +"bAQ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/wall,/area/crew_quarters/sleep) "bAR" = (/turf/simulated/floor{icon_state = "bot"},/area/hallway/primary/central/sw) "bAS" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "hop"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/crew_quarters/heads) "bAT" = (/obj/machinery/computer/card,/turf/simulated/floor{icon_state = "blue"; dir = 10},/area/crew_quarters/heads) @@ -4117,7 +4117,7 @@ "bBi" = (/obj/structure/closet/secure_closet/chemical,/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/chemistry) "bBj" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 101.325; on = 1; pressure_checks = 1},/obj/machinery/door_control{desc = "A remote control switch for the medbay foyer."; id = "MedbayFoyerPort"; name = "Medbay Doors Control"; normaldoorcontrol = 1; pixel_x = -26; pixel_y = 6; range = 3; req_access_txt = null},/turf/simulated/floor{tag = "icon-whiteblue (NORTHWEST)"; icon_state = "whiteblue"; dir = 9},/area/medical/medbay2) "bBk" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor{tag = "icon-whiteblue (NORTHEAST)"; icon_state = "whiteblue"; dir = 5},/area/medical/medbay2) -"bBl" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area) +"bBl" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "bBm" = (/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/cell_charger,/obj/item/weapon/gun/syringe,/turf/simulated/floor{tag = "icon-whiteblue (NORTHWEST)"; icon_state = "whiteblue"; dir = 9},/area/medical/medbay3) "bBn" = (/obj/structure/closet/secure_closet/medical3,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay3) "bBo" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay3) @@ -4148,17 +4148,17 @@ "bBN" = (/obj/structure/table,/obj/structure/window/reinforced/tinted{dir = 4; icon_state = "twindow"; tag = ""},/obj/item/device/mmi/posibrain,/obj/item/device/robotanalyzer,/turf/simulated/floor{dir = 8; icon_state = "whitecorner"},/area/assembly/robotics) "bBO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) "bBP" = (/obj/machinery/door_control{id = "robotics2"; name = "Robotics Lab Shutters Control"; pixel_x = 24; pixel_y = -24; req_access_txt = "29"},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) -"bBQ" = (/obj/structure/table/reinforced,/obj/item/weapon/folder/white,/obj/item/weapon/pen,/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "robotics2"; name = "Robotics Lab Shutters"; opacity = 0},/obj/machinery/door/window/eastright{base_state = "left"; dir = 8; icon_state = "left"; name = "Robotics Desk"; req_access_txt = "47"},/turf/simulated/floor/plating,/area/assembly/robotics) +"bBQ" = (/obj/structure/table/reinforced,/obj/item/weapon/folder/white,/obj/item/weapon/pen,/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "robotics2"; name = "Robotics Lab Shutters"; opacity = 0},/obj/machinery/door/window/eastright{base_state = "left"; dir = 8; icon_state = "left"; name = "Robotics Desk"; req_access_txt = "29"},/turf/simulated/floor/plating,/area/assembly/robotics) "bBR" = (/obj/machinery/light{dir = 8},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{dir = 2; icon_state = "whitecorner"},/area/medical/research{name = "Research Division"}) "bBS" = (/obj/effect/landmark{name = "lightsout"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "whitehall"; dir = 2},/area/medical/research{name = "Research Division"}) "bBT" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{dir = 8; icon_state = "whitecorner"},/area/medical/research{name = "Research Division"}) "bBU" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "rdlab2"; name = "Research and Development Lab Shutters"; opacity = 0},/obj/machinery/door/window/eastright{base_state = "left"; dir = 1; icon_state = "left"; name = "Research and Development Desk"; req_access_txt = "47"},/turf/simulated/floor{icon_state = "white"},/area/toxins/lab) -"bBV" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area) +"bBV" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "bBW" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/glass_research{name = "Research and Development"; req_access_txt = "47"},/turf/simulated/floor{icon_state = "white"},/area/toxins/lab) "bBX" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"bBY" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating/airless,/area) -"bBZ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area) -"bCa" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area) +"bBY" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) +"bBZ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) +"bCa" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "bCb" = (/obj/structure/table,/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "research_shuttle"; pixel_x = -8; pixel_y = -25; req_access_txt = "13;65"; tag_door = "research_shuttle_hatch"},/turf/simulated/shuttle/floor,/area/shuttle/research/station) "bCc" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "cargo_bay_door"; locked = 1; name = "Cargo Docking Hatch"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/quartermaster/storage) "bCd" = (/turf/simulated/floor/plating,/area/quartermaster/storage) @@ -4177,7 +4177,7 @@ "bCq" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/pdapainter,/turf/simulated/floor/carpet,/area/crew_quarters/heads) "bCr" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/carpet,/area/crew_quarters/heads) "bCs" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor,/area/crew_quarters/heads) -"bCt" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = "0"},/turf/simulated/wall/r_wall,/area) +"bCt" = (/turf/simulated/wall,/area/crew_quarters/toilet) "bCu" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor,/area/engine/gravitygenerator) "bCv" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/engine/gravitygenerator) "bCw" = (/obj/machinery/light_switch{pixel_y = -23},/obj/machinery/camera{c_tag = "Gravity Generator Room South"; dir = 8; network = list("SS13")},/obj/machinery/light{dir = 4},/turf/simulated/floor,/area/engine/gravitygenerator) @@ -4246,7 +4246,7 @@ "bDH" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/medical/research{name = "Research Division"}) "bDI" = (/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/medical/research{name = "Research Division"}) "bDJ" = (/obj/structure/closet/emcloset,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_oxygen,/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/medical/research{name = "Research Division"}) -"bDK" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/shuttle/plating,/area) +"bDK" = (/turf/simulated/wall/r_wall,/area/maintenance/auxsolarstarboard) "bDL" = (/turf/simulated/shuttle/wall{icon_state = "swall_s5"; dir = 2},/area/shuttle/research/station) "bDM" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "research_shuttle_hatch"; locked = 1; name = "External Hatch"; req_access_txt = "13"},/turf/simulated/shuttle/floor,/area/shuttle/research/station) "bDN" = (/turf/simulated/shuttle/wall{icon_state = "swall_s9"; dir = 2},/area/shuttle/research/station) @@ -4258,7 +4258,7 @@ "bDT" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/quartermaster/office) "bDU" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/quartermaster/office) "bDV" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/glass_mining{name = "Cargo Office"; req_access_txt = "50"},/turf/simulated/floor,/area/quartermaster/office) -"bDW" = (/obj/machinery/lapvend,/turf/simulated/floor,/area/quartermaster/office) +"bDW" = (/obj/machinery/door_control{id = "alienshutters"; name = "Alien Blast Shutter Control"; pixel_x = -26; pixel_y = -2; req_access_txt = "0"},/obj/machinery/camera{c_tag = "Xeno Shuttle North"; dir = 4; network = list("Xeno")},/turf/simulated/floor/plating/airless,/area/xenos_station/start) "bDX" = (/obj/structure/closet/secure_closet/hop2,/turf/simulated/floor,/area/crew_quarters/heads) "bDY" = (/turf/simulated/floor,/area/crew_quarters/heads) "bDZ" = (/obj/structure/table,/obj/item/weapon/pen,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/obj/item/device/megaphone,/turf/simulated/floor,/area/crew_quarters/heads) @@ -4268,7 +4268,7 @@ "bEd" = (/obj/machinery/power/apc{dir = 1; name = "Messaging Server APC"; pixel_y = 24},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = "0"},/turf/simulated/floor/bluegrid,/area/server) "bEe" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/item/device/radio/intercom{broadcasting = 0; name = "Station Intercom (General)"; pixel_y = 20},/turf/simulated/floor{icon_state = "dark"},/area/server) "bEf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/engineering{name = "Gravity Generator"; req_access_txt = "0"; req_one_access_txt = "10;30"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "dark"},/area/engine/gravitygenerator) -"bEg" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/turf/simulated/wall/r_wall,/area) +"bEg" = (/turf/simulated/wall/r_wall,/area/maintenance/abandonedbar) "bEh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/space,/area) "bEi" = (/obj/machinery/power/apc{dir = 8; name = "Teleporter APC"; pixel_x = -24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/teleporter) "bEj" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/stool,/turf/simulated/floor,/area/teleporter) @@ -4280,10 +4280,10 @@ "bEp" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/hallway/primary/central/sw) "bEq" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR: EMERGENCY ENTRANCE'."; name = "KEEP CLEAR: EMERGENCY ENTRANCE"; pixel_x = 32; pixel_y = 0},/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/hallway/primary/central/sw) "bEr" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/backpack/medic,/obj/item/roller,/obj/item/roller,/obj/item/roller,/obj/item/weapon/storage/toolbox/emergency,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/medbay2) -"bEs" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{id_tag = "MedbayFoyer"; name = "Medical Supplies"; req_access_txt = "5"},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/medbay2) +"bEs" = (/turf/simulated/wall/r_wall{desc = "A specially coated wall that resists temperatures for Science"; max_temperature = 1e+009; name = "Coated Reinforced Wall"},/area/maintenance/fsmaint2) "bEt" = (/obj/machinery/smartfridge/medbay,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) "bEu" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/medical/medbay2) -"bEv" = (/obj/structure/table,/obj/item/bodybag/cryobag{pixel_x = -3},/obj/item/bodybag/cryobag,/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/obj/item/device/flashlight/pen,/obj/item/device/flashlight/pen,/obj/item/device/flashlight/pen,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/tie/stethoscope,/obj/item/clothing/tie/stethoscope,/obj/item/clothing/tie/stethoscope,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/medbay3) +"bEv" = (/obj/structure/table,/obj/item/bodybag/cryobag{pixel_x = -3},/obj/item/bodybag/cryobag,/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/obj/item/device/flashlight/pen,/obj/item/device/flashlight/pen,/obj/item/device/flashlight/pen,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/accessory/stethoscope,/obj/item/clothing/accessory/stethoscope,/obj/item/clothing/accessory/stethoscope,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/medbay3) "bEw" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/item/roller,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay3) "bEx" = (/turf/simulated/floor{icon_state = "white"},/area/medical/medbay3) "bEy" = (/obj/structure/table,/obj/item/weapon/storage/box/beakers,/obj/item/weapon/storage/box/syringes{pixel_x = 4; pixel_y = 4},/obj/item/weapon/storage/box/syringes,/obj/machinery/power/apc{dir = 4; name = "Medbay Equipment APC"; pixel_x = 25},/obj/structure/cable,/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/medical/medbay3) @@ -4291,9 +4291,9 @@ "bEA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment,/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/medical/medbay2) "bEB" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock/glass_medical{id_tag = "GeneticsDoor"; name = "Genetics Cloning"; req_access_txt = "0"; req_one_access_txt = "5;9"},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics_cloning) "bEC" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/door/airlock/maintenance{req_access_txt = "9"},/turf/simulated/floor{icon_state = "white"},/area/maintenance/asmaint) -"bED" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area) +"bED" = (/obj/machinery/door/poddoor{id = "chapelgun"; name = "Chapel Launcher Door"},/turf/simulated/floor/plating,/area/chapel/main) "bEE" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/glass_research{name = "Robotics Lab"; req_access_txt = "29"; req_one_access_txt = "0"},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) -"bEF" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area) +"bEF" = (/turf/simulated/wall/r_wall,/area/chapel/main) "bEG" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) "bEH" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/medical/research{name = "Research Division"}) "bEI" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor{dir = 9; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) @@ -4310,9 +4310,9 @@ "bET" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/research_shuttle_dock) "bEU" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/research{name = "Research Division"}) "bEV" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/medical/research{name = "Research Division"}) -"bEW" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area) -"bEX" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area) -"bEY" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area) +"bEW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/crew_quarters/sleep) +"bEX" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/crew_quarters/toilet) +"bEY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/crew_quarters/toilet) "bEZ" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "research_dock_outer"; locked = 1; name = "Shuttle Airlock"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/medical/research{name = "Research Division"}) "bFa" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "research_dock_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = 8; req_access_txt = "13;65"},/turf/space,/area) "bFb" = (/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/quartermaster/storage) @@ -4323,7 +4323,7 @@ "bFg" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor,/area/quartermaster/office) "bFh" = (/obj/machinery/light,/obj/machinery/computer/merch,/turf/simulated/floor,/area/quartermaster/office) "bFi" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "bluecorner"},/area/hallway/primary/central/sw) -"bFj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area) +"bFj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/sign/poster{pixel_x = 0; pixel_y = 0},/turf/simulated/wall,/area/crew_quarters/bar) "bFk" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor{icon_state = "bot"},/area/hallway/primary/central/sw) "bFl" = (/obj/machinery/computer/security/mining{network = list("Mining Outpost")},/obj/machinery/keycard_auth{pixel_x = -24; pixel_y = 0},/turf/simulated/floor{dir = 9; icon_state = "blue"},/area/crew_quarters/heads) "bFm" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/obj/effect/landmark/start{name = "Head of Personnel"},/turf/simulated/floor,/area/crew_quarters/heads) @@ -4340,7 +4340,7 @@ "bFx" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/obj/effect/decal/warning_stripes/south,/turf/simulated/floor,/area/teleporter) "bFy" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/effect/decal/warning_stripes/south,/turf/simulated/floor,/area/teleporter) "bFz" = (/obj/effect/decal/warning_stripes/south,/turf/simulated/floor,/area/teleporter) -"bFA" = (/obj/machinery/shieldwallgen,/obj/structure/window/basic{dir = 8},/obj/effect/decal/warning_stripes/yellow/hollow,/turf/simulated/floor,/area/teleporter) +"bFA" = (/obj/machinery/shieldwallgen,/obj/effect/decal/warning_stripes/yellow/hollow,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor,/area/teleporter) "bFB" = (/obj/machinery/shieldwallgen,/obj/effect/decal/warning_stripes/yellow/hollow,/turf/simulated/floor,/area/teleporter) "bFC" = (/obj/structure/closet/crate,/turf/simulated/floor,/area/teleporter) "bFD" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/sign/securearea{pixel_x = -32; pixel_y = 0},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/hallway/primary/central/sw) @@ -4372,7 +4372,7 @@ "bGd" = (/obj/structure/table,/obj/item/device/flashlight/pen,/obj/item/device/flashlight/pen,/obj/item/weapon/hand_labeler,/obj/structure/closet/walllocker/emerglocker/north,/turf/simulated/floor{tag = "icon-whitepurple (NORTH)"; icon_state = "whitepurple"; dir = 1},/area/medical/genetics) "bGe" = (/obj/structure/closet/wardrobe/genetics_white,/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor{tag = "icon-whitepurple (NORTH)"; icon_state = "whitepurple"; dir = 1},/area/medical/genetics) "bGf" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; external_pressure_bound = 101; on = 1; pressure_checks = 1},/turf/simulated/floor{tag = "icon-whitepurple (NORTHEAST)"; icon_state = "whitepurple"; dir = 5},/area/medical/genetics) -"bGg" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/door/airlock/research{name = "Genetics Research"; req_access_txt = "47;9"},/turf/simulated/floor{icon_state = "white"},/area/medical/research{name = "Research Division"}) +"bGg" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/turf/simulated/wall,/area/crew_quarters/toilet) "bGh" = (/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{dir = 8; icon_state = "whiteblue"},/area/medical/research{name = "Research Division"}) "bGi" = (/obj/machinery/camera{c_tag = "Research Hallway West"; dir = 2; network = list("Research","SS13")},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor{icon_state = "white"},/area/medical/research{name = "Research Division"}) "bGj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/item/device/radio/intercom{pixel_y = 25},/turf/simulated/floor{icon_state = "white"},/area/medical/research{name = "Research Division"}) @@ -4384,9 +4384,9 @@ "bGp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) "bGq" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/effect/landmark/nations{name = "Scientopia"},/turf/simulated/floor{icon_state = "white"},/area/medical/research{name = "Research Division"}) "bGr" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor{dir = 9; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) -"bGs" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/plating,/area) -"bGt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area) -"bGu" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area) +"bGs" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/crew_quarters/bar) +"bGt" = (/turf/simulated/wall,/area/maintenance/fsmaint2) +"bGu" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "bGv" = (/obj/machinery/light{dir = 8},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/floor{icon_state = "white"},/area/medical/research{name = "Research Division"}) "bGw" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/medical/research{name = "Research Division"}) "bGx" = (/obj/machinery/camera{c_tag = "Research Shuttle Dock"; dir = 2; network = list("SS13","Research")},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor{dir = 2; icon_state = "cmo"},/area/medical/research{name = "Research Division"}) @@ -4394,7 +4394,7 @@ "bGz" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "research_dock_inner"; locked = 1; name = "Shuttle Airlock"; req_access_txt = "13"},/turf/simulated/floor{icon_state = "white"},/area/medical/research{name = "Research Division"}) "bGA" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1380; id_tag = "research_dock_pump"},/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/medical/research{name = "Research Division"}) "bGB" = (/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/medical/research{name = "Research Division"}) -"bGC" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area) +"bGC" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "bGD" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad"},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "cargo_bay_door"; locked = 1; name = "Cargo Docking Hatch"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/quartermaster/storage) "bGE" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad"},/turf/simulated/floor/plating,/area/quartermaster/storage) "bGF" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad"},/obj/machinery/status_display/supply_display{pixel_y = -32},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/quartermaster/storage) @@ -4409,9 +4409,9 @@ "bGO" = (/obj/machinery/light,/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/computer/guestpass{pixel_y = -28},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 2; icon_state = "browncorner"},/area/quartermaster/office) "bGP" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/quartermaster/office) "bGQ" = (/obj/structure/noticeboard{pixel_y = -27},/turf/simulated/floor{dir = 8; icon_state = "browncorner"},/area/quartermaster/office) -"bGR" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/quartermaster/office) -"bGS" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/quartermaster/office) -"bGT" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/quartermaster/office) +"bGR" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/maintenance/auxsolarstarboard) +"bGS" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/library) +"bGT" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/maintenance/fsmaint2) "bGU" = (/obj/machinery/camera{c_tag = "Cargo Bay Entrance"; dir = 4; network = list("SS13")},/obj/machinery/atm{pixel_x = -24},/turf/simulated/floor{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central/sw) "bGV" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "blue"; dir = 4},/area/hallway/primary/central/sw) "bGW" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "hopqueue"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor{dir = 4; icon_state = "loadingarea"; tag = "loading"},/area/hallway/primary/central/sw) @@ -4440,7 +4440,7 @@ "bHt" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{tag = "icon-whitebluecorner (WEST)"; icon_state = "whitebluecorner"; dir = 8},/area/medical/medbay2) "bHu" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) "bHv" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/medical/medbay2) -"bHw" = (/obj/structure/noticeboard,/turf/simulated/wall,/area) +"bHw" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/chapel/office) "bHx" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{id_tag = null; name = "Medical Equipment"; req_access_txt = "5"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/medbay3) "bHy" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/medical/medbay2) "bHz" = (/obj/machinery/door/firedoor,/turf/simulated/floor{icon_state = "white"},/area/medical/cryo) @@ -4451,13 +4451,13 @@ "bHE" = (/obj/structure/table,/obj/item/weapon/book/manual/medical_cloning,/obj/item/weapon/storage/box/bodybags,/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics_cloning) "bHF" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/genetics_cloning) "bHG" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics_cloning) -"bHH" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{id_tag = "GeneticsDoor"; name = "Genetics"; req_access_txt = "9"},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics_cloning) +"bHH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/chapel/office) "bHI" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{tag = "icon-whitepurple (WEST)"; icon_state = "whitepurple"; dir = 8},/area/medical/genetics) "bHJ" = (/obj/effect/landmark/start{name = "Geneticist"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics) "bHK" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics) "bHL" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{dir = 2; icon_state = "whitepurplecorner"},/area/medical/genetics) "bHM" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{tag = "icon-whitepurple (SOUTHEAST)"; icon_state = "whitepurple"; dir = 6},/area/medical/genetics) -"bHN" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/door/airlock/research{name = "Genetics Research"; req_access_txt = "47;9"},/turf/simulated/floor{icon_state = "white"},/area/medical/research{name = "Research Division"}) +"bHN" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/wall,/area/chapel/office) "bHO" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "bot"},/area/medical/research{name = "Research Division"}) "bHP" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{dir = 8; icon_state = "whiteblue"},/area/medical/research{name = "Research Division"}) "bHQ" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/medical/research{name = "Research Division"}) @@ -4468,7 +4468,7 @@ "bHV" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) "bHW" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/research{name = "Research Division"}) "bHX" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/turf/simulated/floor{dir = 9; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) -"bHY" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/plating,/area) +"bHY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/chapel/main) "bHZ" = (/obj/structure/table,/obj/machinery/door_control{id = "Biohazard"; name = "Biohazard Shutter Control"; pixel_x = -4; pixel_y = 6; req_access_txt = "47"},/obj/item/weapon/folder/white{pixel_x = 4},/obj/item/weapon/stamp/rd{pixel_x = 5; pixel_y = -2},/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/hor) "bIa" = (/obj/machinery/computer/security/telescreen{desc = "Used for watching the RD's goons from the safety of his office."; name = "Research Monitor"; network = list("Research","Research Outpost","RD"); pixel_x = 0; pixel_y = 2},/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/hor) "bIb" = (/obj/machinery/computer/aifixer,/obj/machinery/requests_console{announcementConsole = 1; department = "Research Director's Desk"; departmentType = 5; name = "Research Director Requests Console"; pixel_x = -2; pixel_y = 30},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/hor) @@ -4476,7 +4476,7 @@ "bId" = (/obj/machinery/light{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/hor) "bIe" = (/obj/machinery/ai_status_display{pixel_y = 32},/turf/simulated/floor{dir = 4; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/crew_quarters/hor) "bIf" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"bIg" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/shuttle/plating,/area) +"bIg" = (/turf/simulated/wall/r_wall,/area/escapepodbay) "bIh" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/turf/simulated/floor{icon_state = "white"},/area/medical/research{name = "Research Division"}) "bIi" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/medical/research{name = "Research Division"}) "bIj" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/obj/machinery/power/apc{dir = 2; name = "Research Shuttle Dock APC"; pixel_y = -24},/obj/structure/cable,/turf/simulated/floor{dir = 2; icon_state = "cmo"},/area/medical/research{name = "Research Division"}) @@ -4525,7 +4525,7 @@ "bJa" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics_cloning) "bJb" = (/obj/effect/landmark/start{name = "Geneticist"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics_cloning) "bJc" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics_cloning) -"bJd" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{id_tag = "GeneticsDoor"; name = "Genetics"; req_access_txt = "9"},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics_cloning) +"bJd" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/crew_quarters/toilet) "bJe" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{tag = "icon-whitepurple (WEST)"; icon_state = "whitepurple"; dir = 8},/area/medical/genetics) "bJf" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics) "bJg" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "white"},/area/medical/genetics) @@ -4542,7 +4542,7 @@ "bJr" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/rack,/obj/item/device/aicard,/turf/simulated/floor{dir = 8; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/crew_quarters/hor) "bJs" = (/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/hor) "bJt" = (/obj/structure/lamarr,/turf/simulated/floor{dir = 4; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/crew_quarters/hor) -"bJu" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/shuttle/plating,/area) +"bJu" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/wall,/area/crew_quarters/bar) "bJv" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/air,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor{icon_state = "white"},/area/medical/research{name = "Research Division"}) "bJw" = (/obj/machinery/computer/shuttle_control/research{req_access = null; req_access_txt = "65"},/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/medical/research{name = "Research Division"}) "bJx" = (/obj/structure/lattice,/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 32},/turf/space,/area) @@ -4603,7 +4603,7 @@ "bKA" = (/obj/effect/landmark/start{name = "Medical Doctor"},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor{icon_state = "white"},/area/medical/cryo) "bKB" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/cryo) "bKC" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 10; initialize_directions = 10},/turf/simulated/floor{icon_state = "white"},/area/medical/cryo) -"bKD" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/wall,/area) +"bKD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/wall,/area/library) "bKE" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable,/obj/item/roller,/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics_cloning) "bKF" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/genetics_cloning) "bKG" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 30},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics_cloning) @@ -4622,7 +4622,7 @@ "bKT" = (/obj/machinery/portable_atmospherics/scrubber/huge,/obj/structure/sign/nosmoking_2{pixel_x = 28},/obj/effect/decal/warning_stripes/yellow/hollow,/turf/simulated/floor{icon_state = "floorgrime"},/area/toxins/storage) "bKU" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) "bKV" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor{dir = 9; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) -"bKW" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area) +"bKW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/wall,/area/library) "bKX" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/hor) "bKY" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/hor) "bKZ" = (/obj/machinery/computer/mecha,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/hor) @@ -4637,7 +4637,7 @@ "bLi" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/quartermaster/qm) "bLj" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/device/megaphone,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/quartermaster/qm) "bLk" = (/obj/structure/table,/obj/item/weapon/folder/yellow,/obj/item/weapon/pen{pixel_x = 4; pixel_y = 4},/obj/item/weapon/pen/red{pixel_x = 2; pixel_y = 6},/turf/simulated/floor,/area/quartermaster/qm) -"bLl" = (/obj/structure/table,/obj/item/weapon/clipboard,/obj/item/weapon/stamp{name = "Quartermaster's stamp"; pixel_x = 0; pixel_y = 0},/turf/simulated/floor,/area/quartermaster/qm) +"bLl" = (/obj/structure/table,/obj/item/weapon/clipboard,/obj/item/weapon/stamp/granted{name = "Quartermaster's stamp"; pixel_x = 0; pixel_y = 0},/turf/simulated/floor,/area/quartermaster/qm) "bLm" = (/obj/structure/disposalpipe/segment,/obj/machinery/camera{c_tag = "Quartermaster's Office"; dir = 8},/turf/simulated/floor,/area/quartermaster/qm) "bLn" = (/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=AIW"; location = "QM"},/turf/simulated/floor,/area/hallway/primary/central/sw) "bLo" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/hallway/primary/central/sw) @@ -4663,12 +4663,12 @@ "bLI" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "acute1"; name = "Acute 1 Privacy Shutters"; opacity = 0},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/sleeper) "bLJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) "bLK" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay2) -"bLL" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) -"bLM" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/disposalpipe/segment,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) -"bLN" = (/obj/structure/grille,/obj/structure/sign/goldenplaque{desc = "Done No Harm."; name = "Best Doctor 2552"},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area) +"bLL" = (/turf/simulated/wall,/area/library) +"bLM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/chapel/office) +"bLN" = (/turf/simulated/wall,/area/chapel/office) "bLO" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/airlock/command{name = "CMO's Office"; req_access_txt = "40"},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/cmo) -"bLP" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) -"bLQ" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) +"bLP" = (/obj/structure/closet/coffin,/obj/machinery/door/window/eastleft{name = "Coffin Storage"; req_access_txt = "22"},/turf/simulated/floor{icon_state = "dark"},/area/chapel/office) +"bLQ" = (/obj/structure/sign/directions/security{dir = 1; pixel_y = 7},/turf/simulated/wall,/area/hallway/primary/central/north) "bLR" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) "bLS" = (/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/medical/medbay2) "bLT" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/structure/table/reinforced,/obj/item/weapon/wrench,/obj/item/weapon/crowbar,/obj/item/weapon/reagent_containers/spray/cleaner,/turf/simulated/floor{icon_state = "white"},/area/medical/cryo) @@ -4741,16 +4741,16 @@ "bNi" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor,/area/hallway/primary/central/sw) "bNj" = (/obj/machinery/iv_drip,/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/sleeper) "bNk" = (/obj/machinery/door_control{id = "acutesep"; name = "Acute Separation Shutters Control"; pixel_y = -25},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) -"bNl" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/cable,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) +"bNl" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/maintenance/fsmaint) "bNm" = (/obj/structure/disposalpipe/segment,/obj/structure/table,/obj/machinery/photocopier/faxmachine{department = "Chief Medical Officer's Office"},/turf/simulated/floor{tag = "icon-whiteblue (NORTHWEST)"; icon_state = "whiteblue"; dir = 9},/area/medical/cmo) "bNn" = (/obj/machinery/light{dir = 1},/obj/structure/filingcabinet/chestdrawer,/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/cmo) "bNo" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/cmo) "bNp" = (/obj/structure/closet/secure_closet/CMO,/obj/machinery/light{dir = 1},/obj/item/clothing/mask/gas,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/weapon/storage/briefcase,/turf/simulated/floor{tag = "icon-whiteblue (NORTHEAST)"; icon_state = "whiteblue"; dir = 5},/area/medical/cmo) -"bNq" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) +"bNq" = (/turf/simulated/wall,/area/hallway/primary/central/ne) "bNr" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) "bNs" = (/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 30},/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/medical/medbay2) -"bNt" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area) -"bNu" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area) +"bNt" = (/turf/simulated/wall/r_wall,/area/hallway/primary/central/ne) +"bNu" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/wall,/area/crew_quarters/bar) "bNv" = (/obj/machinery/computer/scan_consolenew,/obj/structure/window/reinforced,/turf/simulated/floor{tag = "icon-whitepurple (WEST)"; icon_state = "whitepurple"; dir = 8},/area/medical/genetics) "bNw" = (/obj/machinery/dna_scannernew,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/genetics) "bNx" = (/obj/machinery/door/window/southright{dir = 1; name = "Primate Pen"; req_access_txt = "9"},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics) @@ -4772,8 +4772,8 @@ "bNN" = (/obj/structure/closet/secure_closet/RD,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/hor) "bNO" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/hor) "bNP" = (/obj/structure/filingcabinet/chestdrawer,/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/hor) -"bNQ" = (/obj/machinery/atmospherics/pipe/simple/insulated,/turf/simulated/wall/r_wall,/area) -"bNR" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/poddoor{id = "ToxinsVenting"; name = "Toxins Venting Bay Door"; use_power = 0},/turf/simulated/floor/engine,/area) +"bNQ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/machinery/navbeacon{codes_txt = "delivery;dir=2"; freq = 1400; location = "Bar"},/obj/structure/plasticflaps{opacity = 1},/obj/effect/decal/warning_stripes/yellow/hollow,/turf/simulated/floor,/area/maintenance/fsmaint2) +"bNR" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/turf/simulated/wall,/area/crew_quarters/kitchen) "bNS" = (/turf/simulated/shuttle/wall{icon_state = "swall3"; dir = 2},/area/shuttle/mining/station) "bNT" = (/obj/structure/table,/turf/simulated/shuttle/floor,/area/shuttle/mining/station) "bNU" = (/obj/machinery/computer/shuttle_control/mining,/turf/simulated/shuttle/floor,/area/shuttle/mining/station) @@ -4792,7 +4792,7 @@ "bOh" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor,/area/quartermaster/qm) "bOi" = (/obj/machinery/vending/cigarette{pixel_x = 0; pixel_y = 0},/turf/simulated/floor,/area/hallway/primary/central/sw) "bOj" = (/turf/simulated/wall,/area/maintenance/apmaint) -"bOk" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/aft) +"bOk" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/apmaint) "bOl" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "blueshield"; name = "Privacy Shutters"; opacity = 0},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/blueshield) "bOm" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/command{name = "Blueshield's Office"; req_access_txt = "67"},/turf/simulated/floor/wood,/area/blueshield) "bOn" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "blueshield"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/blueshield) @@ -4800,15 +4800,15 @@ "bOp" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/command{name = "NT Representative's Office"; req_access_txt = "73"},/turf/simulated/floor/wood,/area/ntrep) "bOq" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "representative"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/blueshield) "bOr" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/hallway/primary/central/south) -"bOs" = (/obj/structure/sign/directions/engineering,/obj/structure/sign/directions/science{dir = 4; pixel_x = 0; pixel_y = -7},/obj/structure/sign/directions/medical{dir = 4; pixel_y = 7},/turf/simulated/wall,/area) +"bOs" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/wall,/area/crew_quarters/kitchen) "bOt" = (/obj/machinery/door/airlock{name = "Custodial Closet"; req_access_txt = "26"},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/janitor) "bOu" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/asmaint) "bOv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor/shutters{dir = 2; id = "paramedic"; name = "Paramedic Garage"},/turf/simulated/floor,/area/medical/paramedic) "bOw" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/diamond{name = "Paramedic"; req_access_txt = "66"},/turf/simulated/floor,/area/medical/paramedic) -"bOx" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "acutesep"; name = "Acute Separation Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) +"bOx" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/navbeacon{codes_txt = "delivery;dir=2"; freq = 1400; location = "Kitchen"},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/maintenance/fsmaint2) "bOy" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "acutesep"; name = "Acute Separation Privacy Shutters"; opacity = 0},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/sleeper) "bOz" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "acutesep"; name = "Acute Separation Privacy Shutters"; opacity = 0},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/sleeper) -"bOA" = (/obj/structure/sign/greencross,/turf/simulated/wall,/area) +"bOA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/library) "bOB" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/medbay2) "bOC" = (/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 30},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay2) "bOD" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/structure/disposalpipe/segment,/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/cmo) @@ -4837,11 +4837,11 @@ "bPa" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/turf/simulated/floor{dir = 9; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) "bPb" = (/obj/machinery/atmospherics/pipe/simple/insulated,/obj/machinery/camera{c_tag = "Research Toxins Mixing North"; dir = 2; network = list("Research","SS13"); pixel_x = 0},/turf/simulated/floor{icon_state = "white"},/area/toxins/mixing) "bPc" = (/obj/machinery/atmospherics/pipe/simple/insulated{dir = 6},/obj/machinery/light{dir = 1; in_use = 1},/turf/simulated/floor{icon_state = "white"},/area/toxins/mixing) -"bPd" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction{dir = 4},/turf/simulated/wall/r_wall{desc = "A specially coated wall that resists temperatures for Science"; max_temperature = 1e+009; name = "Coated Reinforced Wall"},/area) +"bPd" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/wall,/area/library) "bPe" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 4},/turf/simulated/floor/engine,/area/toxins/mixing) "bPf" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 10},/turf/simulated/floor/engine,/area/toxins/mixing) -"bPg" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area) -"bPh" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'BOMB RANGE"; name = "BOMB RANGE"},/turf/simulated/wall/r_wall,/area) +"bPg" = (/obj/structure/closet/coffin,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/chapel/office) +"bPh" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/hallway/primary/central/ne) "bPi" = (/turf/simulated/shuttle/floor,/area/shuttle/mining/station) "bPj" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor,/area/shuttle/mining/station) "bPk" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/miningdock) @@ -4857,7 +4857,7 @@ "bPu" = (/obj/structure/closet/secure_closet/quartermaster,/turf/simulated/floor,/area/quartermaster/qm) "bPv" = (/obj/structure/table,/obj/item/weapon/coin/silver,/turf/simulated/floor,/area/quartermaster/qm) "bPw" = (/obj/structure/table,/obj/item/weapon/cartridge/quartermaster{pixel_x = 6; pixel_y = 5},/obj/item/weapon/cartridge/quartermaster,/obj/item/weapon/cartridge/quartermaster{pixel_x = -4; pixel_y = 7},/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor,/area/quartermaster/qm) -"bPx" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/aft) +"bPx" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/apmaint) "bPy" = (/obj/machinery/light{dir = 1},/obj/structure/flora/kirbyplants,/obj/machinery/newscaster/security_unit{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/blueshield) "bPz" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor/wood,/area/blueshield) "bPA" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/wood,/area/blueshield) @@ -4878,7 +4878,7 @@ "bPP" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/janitor) "bPQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/reagent_dispensers/spacecleanertank{pixel_y = 30},/turf/simulated/floor,/area/janitor) "bPR" = (/obj/machinery/door/window/westleft{name = "Janitoral Delivery"; req_access_txt = "26"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "delivery"},/area/janitor) -"bPS" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "Janitor"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "bot"},/area/janitor) +"bPS" = (/obj/machinery/vending/cola,/turf/simulated/floor{icon_state = "dark"},/area/hallway/primary/central/ne) "bPT" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/asmaint) "bPU" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/light{dir = 8},/obj/item/device/radio/intercom{broadcasting = 0; name = "Station Intercom (General)"; pixel_y = 20},/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/turf/simulated/floor{dir = 4; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/medical/paramedic) "bPV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/vehicle/train/ambulance/engine,/turf/simulated/floor{icon_state = "white"},/area/medical/paramedic) @@ -4946,7 +4946,7 @@ "bRf" = (/obj/structure/disposalpipe/segment,/obj/effect/landmark/start{name = "Shaft Miner"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/quartermaster/miningdock) "bRg" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/quartermaster/miningdock) "bRh" = (/obj/item/weapon/beach_ball/holoball,/turf/simulated/floor/plating,/area/maintenance/apmaint) -"bRi" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plating,/area/maintenance/aft) +"bRi" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plating,/area/maintenance/apmaint) "bRj" = (/obj/machinery/photocopier,/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/obj/machinery/light_switch{pixel_x = -25},/turf/simulated/floor/wood,/area/blueshield) "bRk" = (/turf/simulated/floor{icon_state = "bcarpet05"},/area/blueshield) "bRl" = (/turf/simulated/floor/wood,/area/blueshield) @@ -4992,7 +4992,7 @@ "bRZ" = (/obj/item/weapon/cigbutt,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "floorgrime"},/area/toxins/storage) "bSa" = (/obj/effect/decal/warning_stripes/yellow,/obj/machinery/portable_atmospherics/canister/toxins,/turf/simulated/floor{icon_state = "floorgrime"},/area/toxins/storage) "bSb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/medical/research{name = "Research Division"}) -"bSc" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/asmaint2) +"bSc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/crew_quarters/bar) "bSd" = (/obj/machinery/atmospherics/valve,/turf/simulated/floor{icon_state = "white"},/area/toxins/mixing) "bSe" = (/obj/machinery/atmospherics/valve,/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/turf/simulated/floor{icon_state = "white"},/area/toxins/mixing) "bSf" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 2; frequency = 1443; icon_state = "on"; id = "air_in"; on = 1},/turf/simulated/floor/engine,/area/toxins/mixing) @@ -5023,7 +5023,7 @@ "bSE" = (/obj/structure/table,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/machinery/requests_console{department = "Janitorial"; departmentType = 1; pixel_y = -29},/obj/item/weapon/reagent_containers/spray/cleaner,/turf/simulated/floor,/area/janitor) "bSF" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor,/area/janitor) "bSG" = (/obj/machinery/light,/obj/structure/janitorialcart,/turf/simulated/floor,/area/janitor) -"bSH" = (/obj/item/weapon/legcuffs/beartrap,/obj/item/weapon/legcuffs/beartrap,/obj/item/weapon/storage/box/mousetraps,/obj/item/weapon/storage/box/mousetraps,/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor,/area/janitor) +"bSH" = (/obj/item/weapon/restraints/legcuffs/beartrap,/obj/item/weapon/restraints/legcuffs/beartrap,/obj/item/weapon/storage/box/mousetraps,/obj/item/weapon/storage/box/mousetraps,/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor,/area/janitor) "bSI" = (/turf/simulated/floor,/area/janitor) "bSJ" = (/obj/structure/reagent_dispensers/watertank,/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/machinery/light_switch{pixel_y = -23},/turf/simulated/floor,/area/janitor) "bSK" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/maintenance/asmaint) @@ -5036,15 +5036,15 @@ "bSR" = (/obj/machinery/door_control{id = "acute2"; name = "Acute 2 Shutters Control"; pixel_x = 6; pixel_y = -25},/obj/machinery/door_control{id = "scansep"; name = "Scanning Room Separation Shutters Control"; pixel_x = -6; pixel_y = -25},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) "bSS" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 2; icon_state = "whitebluecorner"; tag = "icon-whitebluecorner"},/area/medical/medbay2) "bST" = (/obj/machinery/vending/medical,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{tag = "icon-whiteblue (SOUTHEAST)"; icon_state = "whiteblue"; dir = 6},/area/medical/medbay2) -"bSU" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/disposalpipe/segment,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) +"bSU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/wall,/area/crew_quarters/bar) "bSV" = (/turf/simulated/floor{icon_state = "white"},/area/medical/cmo) "bSW" = (/obj/structure/stool/bed/chair/office/dark{dir = 1},/obj/effect/landmark/start{name = "Chief Medical Officer"},/turf/simulated/floor{icon_state = "white"},/area/medical/cmo) -"bSX" = (/obj/structure/table,/obj/item/weapon/paper_bin,/obj/item/weapon/pen,/obj/item/weapon/folder/white{pixel_y = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/weapon/reagent_containers/food/drinks/coffee,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/tie/stethoscope,/obj/item/weapon/stamp/cmo,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/medical/cmo) -"bSY" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) +"bSX" = (/obj/structure/table,/obj/item/weapon/paper_bin,/obj/item/weapon/pen,/obj/item/weapon/folder/white{pixel_y = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/weapon/reagent_containers/food/drinks/coffee,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/accessory/stethoscope,/obj/item/weapon/stamp/cmo,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/medical/cmo) +"bSY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/crew_quarters/bar) "bSZ" = (/obj/machinery/photocopier,/turf/simulated/floor{tag = "icon-whiteblue (SOUTHWEST)"; icon_state = "whiteblue"; dir = 10},/area/medical/medbay2) "bTa" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/turf/simulated/floor{tag = "icon-whitebluecorner (WEST)"; icon_state = "whitebluecorner"; dir = 8},/area/medical/medbay2) "bTb" = (/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay2) -"bTc" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "staffroom"; name = "Staff Room Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) +"bTc" = (/turf/simulated/wall,/area/crew_quarters/kitchen) "bTd" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/medical/medbreak) "bTe" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/stool,/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/medical/medbreak) "bTf" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/drinks/britcup,/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/medical/medbreak) @@ -5075,7 +5075,7 @@ "bTE" = (/obj/structure/grille,/obj/structure/window/plasmareinforced{dir = 8},/obj/structure/window/plasmareinforced{explosion_resistance = 10},/obj/structure/window/plasmareinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/insulated,/obj/machinery/meter,/turf/simulated/floor/plating,/area/toxins/mixing) "bTF" = (/obj/structure/grille,/obj/structure/window/plasmareinforced{explosion_resistance = 10},/obj/structure/window/plasmareinforced{dir = 1},/turf/simulated/floor/plating,/area/toxins/mixing) "bTG" = (/obj/structure/grille,/obj/structure/window/plasmareinforced{dir = 4},/obj/structure/window/plasmareinforced{explosion_resistance = 10},/obj/structure/window/plasmareinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/insulated,/obj/machinery/meter,/turf/simulated/floor/plating,/area/toxins/mixing) -"bTH" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'BOMB RANGE"; name = "BOMB RANGE"},/turf/simulated/wall,/area) +"bTH" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=2"; freq = 1400; location = "Hydroponics"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/maintenance/fsmaint2) "bTI" = (/obj/structure/closet/crate,/turf/simulated/shuttle/floor,/area/shuttle/mining/station) "bTJ" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/shuttle/mining/station) "bTK" = (/obj/structure/ore_box,/turf/simulated/shuttle/floor,/area/shuttle/mining/station) @@ -5085,30 +5085,30 @@ "bTO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/apmaint) "bTP" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/apmaint) "bTQ" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/closet/crate,/turf/simulated/floor/plating,/area/maintenance/aft) -"bTR" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/aft) +"bTR" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/apmaint) "bTS" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/wood,/area/blueshield) "bTT" = (/obj/structure/stool/bed/chair/office/dark,/turf/simulated/floor/carpet,/area/ntrep) "bTU" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/wood,/area/ntrep) "bTV" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor{dir = 8; icon_state = "cautioncorner"},/area/hallway/primary/aft) "bTW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/hallway/primary/aft) "bTX" = (/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"bTY" = (/obj/machinery/door/airlock/maintenance{name = "Custodial Maintenance"; req_access_txt = "26"},/turf/simulated/floor/plating,/area/maintenance/asmaint) +"bTY" = (/turf/simulated/wall,/area/hydroponics) "bTZ" = (/obj/machinery/power/apc{dir = 8; name = "Medbay Maintenance APC"; pixel_x = -24},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/plating,/area/maintenance/asmaint) "bUa" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/grille{density = 0; icon_state = "brokengrille"},/turf/simulated/floor/plating,/area/maintenance/asmaint) -"bUb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock/maintenance{name = "Paramedic Maintenance"; req_access_txt = "66"},/turf/simulated/floor/plating,/area/maintenance/asmaint) +"bUb" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/hydroponics) "bUc" = (/turf/simulated/wall,/area/medical/sleeper) "bUd" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "scansep"; name = "Scanning Room Separation Shutters"; opacity = 0},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) "bUe" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/medbay2) "bUf" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay2) -"bUg" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/wall,/area) -"bUh" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/cable,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/disposalpipe/segment,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) +"bUg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/wall,/area/hydroponics) +"bUh" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/maintenance{name = "Hydroponics Maintenance"; req_access_txt = "35"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/plating,/area/hydroponics) "bUi" = (/obj/machinery/light,/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor{dir = 10; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/cmo) "bUj" = (/obj/structure/table,/obj/item/device/radio/intercom{broadcasting = 0; canhear_range = 5; freerange = 0; frequency = 1485; listening = 1; name = "Station Intercom (Medbay)"; pixel_x = 0; pixel_y = -30},/obj/item/device/megaphone,/obj/item/weapon/reagent_containers/glass/bottle/stoxin,/turf/simulated/floor{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/cmo) "bUk" = (/turf/simulated/floor{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/cmo) "bUl" = (/obj/machinery/computer/crew,/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 6; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/cmo) -"bUm" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/cable,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) +"bUm" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/hydroponics) "bUn" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/medbay2) -"bUo" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "staffroom"; name = "Staff Room Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) +"bUo" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/wall,/area/chapel/office) "bUp" = (/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable,/obj/machinery/light,/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/medical/medbreak) "bUq" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/medical/medbreak) "bUr" = (/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/structure/stool,/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/medical/medbreak) @@ -5151,7 +5151,7 @@ "bVc" = (/obj/item/device/radio/intercom{pixel_y = 25},/obj/machinery/camera{c_tag = "Research Toxins Launch Room"; dir = 4; network = list("Research","SS13"); pixel_y = -22},/obj/machinery/light{dir = 8},/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor,/area/toxins/mixing) "bVd" = (/obj/machinery/driver_button{dir = 2; id = "toxinsdriver"; pixel_y = 24},/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/toxins/mixing) "bVe" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/computer/security/telescreen{desc = "Used for watching the test chamber."; layer = 4; name = "Test Chamber Telescreen"; network = list("Toxins"); pixel_x = 32; pixel_y = 0},/obj/machinery/alarm{pixel_y = 25},/turf/simulated/floor,/area/toxins/mixing) -"bVf" = (/obj/structure/grille,/obj/structure/window/plasmareinforced{dir = 4},/obj/structure/window/plasmareinforced{dir = 8},/obj/structure/window/plasmareinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area) +"bVf" = (/obj/structure/sign/securearea,/turf/simulated/wall/r_wall,/area/gateway) "bVg" = (/turf/simulated/floor/airless{dir = 9; icon_state = "warning"},/area/toxins/test_area) "bVh" = (/turf/simulated/floor/airless{tag = "icon-warning (NORTH)"; icon_state = "warning"; dir = 1},/area/toxins/test_area) "bVi" = (/turf/simulated/shuttle/wall{icon_state = "swall_s5"; dir = 2},/area/shuttle/mining/station) @@ -5163,11 +5163,11 @@ "bVo" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/miningdock) "bVp" = (/obj/structure/reagent_dispensers/fueltank,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/apmaint) "bVq" = (/obj/structure/reagent_dispensers/watertank,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/apmaint) -"bVr" = (/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/effect/decal/cleanable/dirt,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plating,/area/maintenance/apmaint) +"bVr" = (/obj/machinery/power/apc{dir = 2; name = "Cargo Maintenance APC"; pixel_y = -24},/obj/effect/decal/cleanable/dirt,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plating,/area/maintenance/apmaint) "bVs" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/apmaint) "bVt" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/maintenance/aft) "bVu" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/sortjunction{dir = 8; icon_state = "pipe-j1s"; name = "HoP Office"; sortType = 15},/turf/simulated/floor/plating,/area/maintenance/aft) -"bVv" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/maintenance/aft) +"bVv" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/maintenance/apmaint) "bVw" = (/obj/machinery/keycard_auth{pixel_x = -24; pixel_y = 0},/obj/machinery/door/window{dir = 1; name = "Desk Door"; req_access_txt = "67"},/turf/simulated/floor/wood,/area/blueshield) "bVx" = (/obj/structure/table/woodentable,/obj/item/ashtray/glass{pixel_x = -4; pixel_y = -4},/obj/item/weapon/lighter/zippo/fluff/li_matsuda_1{pixel_x = 7; pixel_y = 4},/turf/simulated/floor{icon_state = "bcarpet05"},/area/blueshield) "bVy" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin,/obj/item/weapon/pen/blue,/obj/item/weapon/folder/blue{pixel_x = 4; pixel_y = 6},/obj/item/weapon/paper/blueshield,/turf/simulated/floor{icon_state = "bcarpet05"},/area/blueshield) @@ -5193,16 +5193,16 @@ "bVS" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/medical/sleeper) "bVT" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 1},/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/medical/sleeper) "bVU" = (/obj/machinery/door_control{id = "scanhide"; name = "Scanning Room Privacy Shutters Control"; pixel_x = 6; pixel_y = 25},/obj/machinery/camera{c_tag = "Medbay Scanning"; network = list("SS13")},/obj/machinery/atmospherics/unary/cold_sink/freezer{dir = 8; icon_state = "freezer_0"; tag = ""},/obj/machinery/door_control{id = "scansep"; name = "Scanning Room Separation Shutters Control"; pixel_x = -6; pixel_y = 25},/turf/simulated/floor{dir = 5; icon_state = "blue"},/area/medical/sleeper) -"bVV" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "scanhide"; name = "Scanning Room Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) +"bVV" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/hallway/primary/central/ne) "bVW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay2) -"bVX" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/cable,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/disposalpipe/segment,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) -"bVY" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) +"bVX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/hallway/primary/central/ne) +"bVY" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/hallway/primary/central/ne) "bVZ" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{name = "CMO's Office"; req_access_txt = "40"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/cmo) -"bWa" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/cable,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) +"bWa" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/wall,/area/library) "bWb" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/junction{tag = "icon-pipe-j2"; icon_state = "pipe-j2"; dir = 2},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/medbay2) "bWc" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only,/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"; tag = "icon-whitebluecorner"},/area/medical/medbay2) -"bWd" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area) -"bWe" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/wall,/area) +"bWd" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/escapepodbay) +"bWe" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/escapepodbay) "bWf" = (/obj/structure/flora/kirbyplants,/obj/machinery/door_control{id = "psychoffice"; name = "Privacy Shutters Control"; pixel_x = -25; pixel_y = 0},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/wood,/area/medical/psych) "bWg" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/wood,/area/medical/psych) "bWh" = (/obj/machinery/alarm{dir = 1; pixel_y = -22},/turf/simulated/floor/wood,/area/medical/psych) @@ -5240,11 +5240,11 @@ "bWN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/toxins/mixing) "bWO" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor,/area/toxins/mixing) "bWP" = (/obj/machinery/doppler_array{dir = 4},/turf/simulated/floor,/area/toxins/mixing) -"bWQ" = (/obj/structure/grille,/obj/structure/window/plasmareinforced{dir = 4},/obj/structure/window/plasmareinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area) +"bWQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/hydroponics) "bWR" = (/turf/simulated/floor/airless{dir = 8; icon_state = "warning"},/area/toxins/test_area) "bWS" = (/turf/simulated/wall/r_wall,/area/maintenance/apmaint) "bWT" = (/obj/machinery/door/airlock/maintenance{name = "Firefighting equipment"; req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/apmaint) -"bWU" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/aft) +"bWU" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/apmaint) "bWV" = (/obj/machinery/requests_console{announcementConsole = 1; department = "Blueshield"; departmentType = 5; name = "Blueshield Requests Console"; pixel_x = -30},/turf/simulated/floor/wood,/area/blueshield) "bWW" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/obj/effect/landmark/start{name = "Blueshield"},/turf/simulated/floor{icon_state = "bcarpet05"},/area/blueshield) "bWX" = (/obj/structure/table/woodentable,/obj/machinery/computer/skills{req_one_access = null},/turf/simulated/floor{icon_state = "bcarpet05"},/area/blueshield) @@ -5258,7 +5258,7 @@ "bXf" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/structure/disposalpipe/segment,/turf/simulated/floor{dir = 8; icon_state = "cautioncorner"},/area/hallway/primary/aft) "bXg" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/hallway/primary/aft) "bXh" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"bXi" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/wall/r_wall,/area) +"bXi" = (/turf/simulated/wall,/area/blueshield) "bXj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/airlock/maintenance{name = "Firefighting equipment"; req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/asmaint) "bXk" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/asmaint) "bXl" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint) @@ -5288,9 +5288,9 @@ "bXJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) "bXK" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/disposalpipe/segment,/obj/structure/closet/walllocker/emerglocker/north,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) "bXL" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Psych Office"; req_access_txt = "64"},/turf/simulated/floor{icon_state = "white"},/area/medical/psych) -"bXM" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "psychoffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) -"bXN" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "psychoffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) -"bXO" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "psychoffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) +"bXM" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/hallway/primary/central/nw) +"bXN" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/hallway/primary/central/nw) +"bXO" = (/turf/simulated/wall/r_wall,/area/bridge) "bXP" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/extinguisher_cabinet{pixel_x = -24},/turf/simulated/floor{icon_state = "white"},/area/toxins/telesci) "bXQ" = (/obj/machinery/computer/security/telescreen{desc = "Used for watching the telepad chamber."; layer = 4; name = "Telepad Camera Screen"; network = list("Telepad"); pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor{icon_state = "white"},/area/toxins/telesci) "bXR" = (/turf/simulated/floor{icon_state = "white"},/area/toxins/telesci) @@ -5314,13 +5314,13 @@ "bYj" = (/obj/machinery/disposal,/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = -30; pixel_y = 0},/obj/structure/disposalpipe/trunk,/turf/simulated/floor{tag = "icon-warningcorner"; icon_state = "warningcorner"; dir = 2},/area/toxins/mixing) "bYk" = (/turf/simulated/floor{icon_state = "warning"},/area/toxins/mixing) "bYl" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/computer/security/telescreen{desc = "Used for watching the test chamber."; layer = 4; name = "Test Chamber Telescreen"; network = list("Toxins"); pixel_x = 32; pixel_y = 0},/turf/simulated/floor{tag = "icon-warningcorner (NORTH)"; icon_state = "warningcorner"; dir = 1},/area/toxins/mixing) -"bYm" = (/obj/structure/grille,/obj/structure/window/plasmareinforced{dir = 4},/obj/structure/window/plasmareinforced{dir = 8},/obj/structure/window/plasmareinforced{explosion_resistance = 10},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area) +"bYm" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/bridge) "bYn" = (/turf/simulated/floor/airless{dir = 4; icon_state = "warning"},/area/toxins/test_area) "bYo" = (/turf/simulated/floor/airless{tag = "icon-warningcorner (NORTH)"; icon_state = "warningcorner"; dir = 1},/area/toxins/test_area) "bYp" = (/obj/machinery/light/small{dir = 1},/obj/structure/stool,/turf/simulated/floor/plating,/area/maintenance/aft) "bYq" = (/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor/plating,/area/maintenance/aft) "bYr" = (/turf/simulated/floor/plating,/area/maintenance/aft) -"bYs" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/aft) +"bYs" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/apmaint) "bYt" = (/obj/structure/closet/secure_closet/blueshield,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/wood,/area/blueshield) "bYu" = (/obj/machinery/door_control{id = "blueshield"; name = "Privacy Shutters Control"; pixel_x = 0; pixel_y = -24; req_access_txt = "67"},/obj/machinery/computer/crew,/turf/simulated/floor/wood,/area/blueshield) "bYv" = (/obj/structure/table/woodentable,/obj/machinery/light/small/lamp,/obj/machinery/camera{c_tag = "Blueshield's Office"; dir = 1; network = list("SS13")},/turf/simulated/floor/wood,/area/blueshield) @@ -5340,7 +5340,7 @@ "bYJ" = (/obj/structure/table,/obj/item/device/t_scanner,/turf/simulated/floor/plating,/area/maintenance/asmaint) "bYK" = (/obj/structure/rack{dir = 1},/obj/item/clothing/suit/fire/firefighter,/obj/item/weapon/tank/oxygen,/obj/item/clothing/mask/gas,/obj/item/weapon/extinguisher,/obj/item/clothing/head/hardhat/red,/obj/item/clothing/glasses/meson,/turf/simulated/floor/plating,/area/maintenance/asmaint) "bYL" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/grille{density = 0; icon_state = "brokengrille"},/turf/simulated/floor/plating,/area/maintenance/asmaint) -"bYM" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"},/turf/simulated/wall,/area) +"bYM" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/bridge) "bYN" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/medical/sleeper) "bYO" = (/obj/effect/landmark/start{name = "Medical Doctor"},/turf/simulated/floor,/area/medical/sleeper) "bYP" = (/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor,/area/medical/sleeper) @@ -5458,7 +5458,7 @@ "caX" = (/obj/machinery/light/small{dir = 1},/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/turf/simulated/floor/plating,/area/storage/tech) "caY" = (/obj/machinery/camera{c_tag = "Tech Storage"; dir = 2; network = list("SS13")},/obj/machinery/power/apc{dir = 1; name = "Tech Storage APC"; pixel_y = 24},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/circuitboard/cyborgrecharger{pixel_x = -4; pixel_y = -2},/obj/item/weapon/circuitboard/mech_bay_power_console{pixel_x = 2; pixel_y = 2},/obj/item/weapon/circuitboard/mech_recharger,/obj/item/weapon/circuitboard/mechfab{pixel_y = 3},/turf/simulated/floor/plating,/area/storage/tech) "caZ" = (/obj/structure/table,/obj/item/device/analyzer,/obj/item/device/healthanalyzer,/turf/simulated/floor/plating,/area/storage/tech) -"cba" = (/obj/structure/table,/obj/item/device/analyzer/plant_analyzer,/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor/plating,/area/storage/tech) +"cba" = (/obj/structure/table,/obj/item/device/analyzer/plant_analyzer,/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor/plating,/area/storage/tech) "cbb" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plating,/area/storage/tech) "cbc" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{dir = 8; icon_state = "cautioncorner"},/area/hallway/primary/aft) "cbd" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/hallway/primary/aft) @@ -5469,7 +5469,7 @@ "cbi" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/engine/controlroom) "cbj" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/engine/controlroom) "cbk" = (/obj/machinery/disposal,/obj/machinery/camera{c_tag = "Atmospherics Monitoring"; dir = 8; network = list("SS13")},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{icon_state = "caution"; dir = 4},/area/engine/controlroom) -"cbl" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area) +"cbl" = (/turf/simulated/wall,/area/ntrep) "cbm" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/oxygen{name = "Canister: \[O2] (CRYO)"},/obj/machinery/light_switch{name = "light switch "; dir = 2; pixel_x = 0; pixel_y = -22},/turf/simulated/floor{icon_state = "blue"; dir = 10},/area/medical/sleeper) "cbn" = (/obj/machinery/bodyscanner,/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/medical/sleeper) "cbo" = (/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = -28},/obj/machinery/body_scanconsole,/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/medical/sleeper) @@ -5484,14 +5484,14 @@ "cbx" = (/obj/structure/table,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay2) "cby" = (/obj/structure/stool/bed/chair/comfy/teal{tag = "icon-comfychair_teal (WEST)"; icon_state = "comfychair_teal"; dir = 8},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay2) "cbz" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) -"cbA" = (/obj/structure/sign/biohazard,/turf/simulated/wall/r_wall,/area) -"cbB" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area) +"cbA" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/status_display{density = 0; layer = 4},/turf/simulated/floor/plating,/area/bridge) +"cbB" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/bridge) "cbC" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Virology Access"; req_access_txt = "5"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/virology) -"cbD" = (/obj/structure/extinguisher_cabinet,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/wall/r_wall,/area) +"cbD" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/bridge) "cbE" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{id_tag = null; name = "Secondary Storage"; req_access_txt = "39"},/turf/simulated/floor,/area/medical/biostorage) "cbF" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/maintenance{name = "Medbay Maintenance Access"; req_access_txt = "5"},/turf/simulated/floor/plating,/area/maintenance/asmaint) -"cbG" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"},/turf/simulated/wall,/area) -"cbH" = (/obj/machinery/light,/obj/structure/table,/obj/item/weapon/packageWrap,/obj/item/weapon/hand_labeler,/turf/simulated/floor{icon_state = "white"},/area/toxins/telesci) +"cbG" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/window/reinforced/tinted,/turf/simulated/floor/plating,/area/bridge) +"cbH" = (/obj/machinery/light,/obj/structure/table,/obj/item/stack/packageWrap,/obj/item/weapon/hand_labeler,/turf/simulated/floor{icon_state = "white"},/area/toxins/telesci) "cbI" = (/obj/machinery/power/apc{cell_type = 5000; dir = 2; name = "Bridge APC"; pixel_y = -24},/obj/structure/cable,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/table,/obj/item/device/radio,/turf/simulated/floor{icon_state = "white"},/area/toxins/telesci) "cbJ" = (/obj/machinery/camera{c_tag = "Research Telescience"; dir = 1; network = list("Research","SS13")},/obj/structure/disposalpipe/trunk{dir = 4},/obj/machinery/disposal,/turf/simulated/floor{icon_state = "white"},/area/toxins/telesci) "cbK" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "white"},/area/toxins/telesci) @@ -5506,11 +5506,11 @@ "cbT" = (/turf/simulated/floor/airless{dir = 5; icon_state = "warning"},/area/toxins/test_area) "cbU" = (/turf/simulated/floor/airless{tag = "icon-warningcorner (EAST)"; icon_state = "warningcorner"; dir = 4},/area/toxins/test_area) "cbV" = (/obj/machinery/atmospherics/pipe/vent{dir = 2},/turf/simulated/floor/plating/airless,/area) -"cbW" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area) -"cbX" = (/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area) -"cbY" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area) -"cbZ" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/grille,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area) -"cca" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area) +"cbW" = (/turf/simulated/wall,/area/hallway/primary/aft) +"cbX" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/blueshield) +"cbY" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating,/area/bridge) +"cbZ" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/status_display{density = 0; layer = 4},/turf/simulated/floor/plating,/area/bridge) +"cca" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/hallway/primary/aft) "ccb" = (/obj/structure/table,/obj/item/weapon/module/power_control,/obj/item/weapon/airlock_electronics,/turf/simulated/floor/plating,/area/storage/tech) "ccc" = (/turf/simulated/floor/plating,/area/storage/tech) "ccd" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/storage/tech) @@ -5532,7 +5532,7 @@ "cct" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor{icon_state = "dark"},/area/construction) "ccu" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{id_tag = null; name = "Recovery Ward"; req_access_txt = "0"},/turf/simulated/floor{icon_state = "white"},/area/medical/ward) "ccv" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{id_tag = null; name = "Recovery Ward"; req_access_txt = "0"},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/medical/ward) -"ccw" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area) +"ccw" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/bridge) "ccx" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "scanhide"; name = "Scanning Room Shutters"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/medical/medbay2) "ccy" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) "ccz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/virology) @@ -5544,13 +5544,13 @@ "ccF" = (/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/maintenance/asmaint) "ccG" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/asmaint) "ccH" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/maintenance{name = "Telescience Maintenance"; req_access_txt = "47"},/turf/simulated/floor/plating,/area/maintenance/asmaint) -"ccI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/wall/r_wall,/area) -"ccJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/wall/r_wall,/area) +"ccI" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/hallway/primary/central/ne) +"ccJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/hallway/primary/central/ne) "ccK" = (/obj/structure/rack{dir = 1},/obj/item/clothing/mask/gas,/obj/item/clothing/glasses/meson,/turf/simulated/floor/plating,/area/maintenance/asmaint) "ccL" = (/obj/structure/rack{dir = 1},/obj/item/weapon/extinguisher,/obj/item/clothing/head/hardhat/red,/turf/simulated/floor/plating,/area/maintenance/asmaint) "ccM" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/asmaint) "ccN" = (/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/plating,/area/maintenance/asmaint) -"ccO" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/research{name = "Xenobiology Research"; req_access_txt = "47"},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/medical/research{name = "Research Division"}) +"ccO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/crew_quarters/kitchen) "ccP" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/valve,/turf/simulated/floor/plating,/area/maintenance/asmaint2) "ccQ" = (/obj/machinery/power/apc{dir = 1; name = "Science Maintenance APC"; pixel_y = 26},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/plating,/area/maintenance/asmaint2) "ccR" = (/turf/simulated/wall,/area/maintenance/asmaint2) @@ -5561,17 +5561,17 @@ "ccW" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/wall,/area/security/vacantoffice) "ccX" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 5},/turf/simulated/floor/plating/airless,/area) "ccY" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor/plating/airless,/area) -"ccZ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor/plating,/area) +"ccZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/wall,/area/ntrep) "cda" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/reagent_dispensers/fueltank,/obj/machinery/atmospherics/pipe/simple/visible{dir = 10},/turf/simulated/floor/plating,/area/maintenance/incinerator) "cdb" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor/plating,/area/maintenance/incinerator) "cdc" = (/obj/machinery/atmospherics/pipe/tank/toxins{volume = 3200},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cdd" = (/obj/machinery/atmospherics/pipe/tank/oxygen{volume = 3200},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cde" = (/obj/machinery/portable_atmospherics/canister/oxygen,/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) -"cdf" = (/obj/structure/rack{dir = 1},/obj/item/device/flashlight,/obj/item/clothing/glasses/sunglasses,/turf/simulated/floor/plating,/area/maintenance/aft) -"cdg" = (/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/cable,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area) +"cdf" = (/obj/structure/rack{dir = 1},/obj/item/device/flashlight,/obj/item/clothing/glasses/sunglasses,/turf/simulated/floor/plating,/area/maintenance/apmaint) +"cdg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/ntrep) "cdh" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/circuitboard/borgupload{pixel_x = -1; pixel_y = 1},/obj/item/weapon/circuitboard/aiupload{pixel_x = 2; pixel_y = -2},/turf/simulated/floor,/area/storage/tech) "cdi" = (/obj/machinery/camera{c_tag = "Secure Tech Storage"; dir = 2},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/storage/tech) -"cdj" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"},/turf/simulated/wall/r_wall,/area) +"cdj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/crew_quarters/kitchen) "cdk" = (/obj/structure/table,/obj/item/device/aicard,/obj/item/weapon/aiModule/reset,/turf/simulated/floor/plating,/area/storage/tech) "cdl" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/circuitboard/rdconsole{pixel_x = -4},/obj/item/weapon/circuitboard/rdserver{pixel_x = 4; pixel_y = -2},/obj/item/weapon/circuitboard/destructive_analyzer,/obj/item/weapon/circuitboard/protolathe{pixel_x = -2; pixel_y = 3},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/item/weapon/circuitboard/circuit_imprinter{pixel_x = -4; pixel_y = -3},/turf/simulated/floor/plating,/area/storage/tech) "cdm" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/circuitboard/autolathe{pixel_x = 3; pixel_y = -3},/obj/item/weapon/circuitboard/pandemic{pixel_x = -3; pixel_y = 3},/obj/item/weapon/circuitboard/bodyscanner,/obj/item/weapon/circuitboard/bodyscanner_console,/obj/item/weapon/circuitboard/sleeper{pixel_x = 3},/obj/item/weapon/circuitboard/sleep_console{pixel_x = 3},/turf/simulated/floor/plating,/area/storage/tech) @@ -5627,16 +5627,16 @@ "cek" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/mob/living/simple_animal/mouse,/turf/simulated/floor/plating,/area/maintenance/asmaint2) "cel" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/decal/remains/robot,/turf/simulated/floor/plating,/area/maintenance/asmaint2) "cem" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"cen" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/shuttle/plating,/area) +"cen" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/crew_quarters/kitchen) "ceo" = (/obj/structure/disposalpipe/trunk{dir = 4},/obj/structure/disposaloutlet{dir = 8},/turf/simulated/floor/plating/airless,/area) -"cep" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall{desc = "A specially coated wall that resists temperatures for Science"; max_temperature = 1e+009; name = "Coated Reinforced Wall"},/area) -"ceq" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/wall/r_wall{desc = "A specially coated wall that resists temperatures for Science"; max_temperature = 1e+009; name = "Coated Reinforced Wall"},/area) +"cep" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/engine/controlroom) +"ceq" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/wall/r_wall,/area/engine/controlroom) "cer" = (/obj/structure/sign/nosmoking_2{pixel_x = -28},/turf/simulated/floor/plating,/area/maintenance/incinerator) "ces" = (/obj/machinery/atmospherics/binary/pump{dir = 1; name = "Gas Pump"; on = 1},/turf/simulated/floor/plating,/area/maintenance/incinerator) "cet" = (/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "ceu" = (/obj/machinery/atmospherics/binary/pump,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cev" = (/obj/machinery/power/apc{dir = 4; name = "Incinerator APC"; pixel_x = 24; pixel_y = 0},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) -"cew" = (/obj/machinery/light/small{dir = 8},/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/maintenance/aft) +"cew" = (/obj/machinery/light/small{dir = 8},/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/maintenance/apmaint) "cex" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/circuitboard/crew{pixel_x = -1; pixel_y = 1},/obj/item/weapon/circuitboard/card{pixel_x = 2; pixel_y = -2},/obj/item/weapon/circuitboard/communications{pixel_x = 5; pixel_y = -5},/obj/machinery/light/small{dir = 8},/turf/simulated/floor,/area/storage/tech) "cey" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/storage/tech) "cez" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/highsecurity{name = "Secure Tech Storage"; req_access_txt = "19;23"},/turf/simulated/floor/plating,/area/storage/tech) @@ -5679,22 +5679,22 @@ "cfk" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/asmaint) "cfl" = (/obj/item/device/flashlight,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint) "cfm" = (/obj/structure/rack{dir = 1},/obj/item/weapon/storage/box/lights/mixed,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint) -"cfn" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area) -"cfo" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area) +"cfn" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/crew_quarters/kitchen) +"cfo" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/chapel/main) "cfp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2; name = "hazard door south"},/turf/simulated/floor{dir = 2; icon_state = "whitegreen"; tag = "icon-whitehall (WEST)"},/area/toxins/xenobiology) "cfq" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2; name = "hazard door south"},/obj/structure/disposalpipe/segment,/turf/simulated/floor{dir = 2; icon_state = "whitegreen"; tag = "icon-whitehall (WEST)"},/area/toxins/xenobiology) "cfr" = (/obj/machinery/door/firedoor/border_only{dir = 2; name = "hazard door south"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor{dir = 2; icon_state = "whitegreen"; tag = "icon-whitehall (WEST)"},/area/toxins/xenobiology) -"cfs" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plating,/area) -"cft" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor/plating,/area) -"cfu" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area) -"cfv" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area) -"cfw" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area) +"cfs" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/hallway/primary/central/nw) +"cft" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/hallway/primary/central/ne) +"cfu" = (/obj/machinery/smartfridge,/turf/simulated/wall,/area/hydroponics) +"cfv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/security/vacantoffice) +"cfw" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/hallway/primary/central/nw) "cfx" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"cfy" = (/obj/machinery/door/poddoor{id = "disvent"; name = "Incinerator Vent"},/turf/simulated/floor/engine/vacuum,/area) +"cfy" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/wall/r_wall,/area/engine/controlroom) "cfz" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 4; frequency = 1443; icon_state = "on"; id = "air_in"; on = 1},/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/engine/vacuum,/area/maintenance/incinerator) "cfA" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/closet/emcloset,/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor/plating,/area/maintenance/incinerator) "cfB" = (/obj/machinery/atmospherics/binary/pump{dir = 8; on = 1},/obj/machinery/light/small{dir = 1},/obj/structure/sign/fire{pixel_y = 32},/turf/simulated/floor/plating,/area/maintenance/incinerator) -"cfC" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/wall/r_wall{desc = "A specially coated wall that resists temperatures for Science"; max_temperature = 1e+009; name = "Coated Reinforced Wall"},/area) +"cfC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/wall/r_wall,/area/engine/controlroom) "cfD" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cfE" = (/obj/machinery/embedded_controller/radio/airlock/access_controller{frequency = 1449; id_tag = "incinerator_access_control"; name = "Incinerator Access Console"; pixel_x = -26; pixel_y = 6; req_access_txt = "12"; tag_exterior_door = "incinerator_airlock_exterior"; tag_interior_door = "incinerator_airlock_interior"},/obj/machinery/ignition_switch{id = "Incinerator"; pixel_x = -24; pixel_y = -6},/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cfF" = (/obj/machinery/atmospherics/pipe/manifold/visible,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) @@ -5712,7 +5712,7 @@ "cfR" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/engine/controlroom) "cfS" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/engine/controlroom) "cfT" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/engine/controlroom) -"cfU" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/wall/r_wall,/area) +"cfU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/wall,/area/ntrep) "cfV" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor{icon_state = "dark"},/area/construction) "cfW" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor{icon_state = "dark"},/area/construction) "cfX" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor{icon_state = "dark"},/area/construction) @@ -5737,7 +5737,7 @@ "cgq" = (/obj/structure/closet/crate/hydroponics/prespawned,/turf/simulated/floor{dir = 1; icon_state = "whitegreen"},/area/toxins/xenobiology/xenoflora_storage) "cgr" = (/obj/structure/closet/secure_closet/hydroponics{req_access = list(47)},/turf/simulated/floor{dir = 1; icon_state = "whitegreen"},/area/toxins/xenobiology/xenoflora_storage) "cgs" = (/obj/structure/closet/secure_closet/hydroponics{req_access = list(47)},/obj/machinery/light{dir = 1; on = 1},/obj/machinery/light_switch{pixel_x = 27; pixel_y = 0},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor{dir = 5; icon_state = "whitegreen"},/area/toxins/xenobiology/xenoflora_storage) -"cgt" = (/obj/structure/sign/biohazard,/turf/simulated/wall,/area) +"cgt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/hallway/primary/central/nw) "cgu" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/research{name = "Xenobiology Research"; req_access_txt = "47"},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) "cgv" = (/obj/structure/disposalpipe/trunk,/obj/machinery/disposal,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/light{dir = 8},/obj/machinery/power/apc{dir = 1; name = "Xenoflora Laboratory APC"; pixel_x = -1; pixel_y = 26},/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/turf/simulated/floor{dir = 9; icon_state = "whitegreen"},/area/toxins/xenobiology/xenoflora) "cgw" = (/obj/machinery/atmospherics/portables_connector{layer = 2},/obj/machinery/portable_atmospherics/hydroponics{closed_system = 1; name = "isolation tray"},/turf/simulated/floor{dir = 1; icon_state = "whitegreen"},/area/toxins/xenobiology/xenoflora) @@ -5752,7 +5752,7 @@ "cgF" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plating,/area/maintenance/asmaint2) "cgG" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/asmaint2) "cgH" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"cgI" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/wall/r_wall,/area) +"cgI" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/hallway/primary/central/ne) "cgJ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating/airless,/area) "cgK" = (/obj/machinery/door/airlock/external{name = "Toxins Test Chamber"; req_access_txt = "0"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/space,/area/toxins/test_area) "cgL" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plating/airless,/area/toxins/test_area) @@ -5763,13 +5763,13 @@ "cgQ" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cgR" = (/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/obj/machinery/hologram/holopad,/mob/living/simple_animal/mouse,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cgS" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) -"cgT" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/maintenance{name = "Incinerator Access"; req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/asmaint) -"cgU" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/maintenance/aft) -"cgV" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/aft) -"cgW" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area) -"cgX" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area) -"cgY" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/grille,/obj/structure/cable,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area) -"cgZ" = (/obj/structure/table,/obj/item/stack/cable_coil{pixel_x = -3; pixel_y = 3},/obj/item/stack/cable_coil,/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor/plating,/area/storage/tech) +"cgT" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/apmaint) +"cgU" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/maintenance/apmaint) +"cgV" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/window/eastleft{name = "Hydroponics Desk"; req_access_txt = "35"},/obj/machinery/door/window/northleft{dir = 8; icon_state = "left"; name = "Kitchen Desk"; req_access_txt = "28"},/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/hydroponics) +"cgW" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/plating,/area/bridge) +"cgX" = (/turf/simulated/wall/r_wall,/area/hallway/primary/aft) +"cgY" = (/turf/simulated/wall/r_wall,/area/engine/controlroom) +"cgZ" = (/obj/structure/table,/obj/item/stack/cable_coil{pixel_x = -3; pixel_y = 3},/obj/item/stack/cable_coil,/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor/plating,/area/storage/tech) "cha" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/plating,/area/storage/tech) "chb" = (/obj/machinery/requests_console{department = "Tech storage"; pixel_x = 0; pixel_y = -32},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/storage/tech) "chc" = (/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/storage/tech) @@ -5785,12 +5785,12 @@ "chm" = (/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/turf/simulated/floor{icon_state = "dark"},/area/construction) "chn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "dark"},/area/construction) "cho" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Operating Theatre"; req_access_txt = "45"},/obj/machinery/holosign/surgery{id = "surgery1"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) -"chp" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "surgeryobs1"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) -"chq" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "surgeryobs1"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) -"chr" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "surgeryobs1"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) -"chs" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "surgeryobs2"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) -"cht" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "surgeryobs2"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) -"chu" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "surgeryobs2"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area) +"chp" = (/turf/simulated/wall,/area/hallway/primary/starboard/east) +"chq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/library) +"chr" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/bridge) +"chs" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/bridge) +"cht" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable,/turf/simulated/floor/plating,/area/bridge) +"chu" = (/turf/simulated/wall/r_wall,/area/bridge/meeting_room) "chv" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Operating Theatre"; req_access_txt = "45"},/obj/machinery/holosign/surgery{id = "surgery2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "chw" = (/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/virology) "chx" = (/obj/structure/closet/l3closet,/obj/item/clothing/mask/gas,/turf/simulated/floor{icon_state = "blue"; dir = 10},/area/medical/biostorage) @@ -5806,7 +5806,7 @@ "chH" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) "chI" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/toxins/xenobiology/xenoflora) "chJ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor{dir = 10; icon_state = "whitegreen"},/area/toxins/xenobiology/xenoflora) -"chK" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "whitegreen"},/area/toxins/xenobiology/xenoflora) +"chK" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 5},/turf/simulated/floor{dir = 2; icon_state = "whitegreen"},/area/toxins/xenobiology/xenoflora) "chL" = (/obj/machinery/atmospherics/pipe/manifold/visible,/turf/simulated/floor{dir = 2; icon_state = "whitegreen"},/area/toxins/xenobiology/xenoflora) "chM" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 4; initialize_directions = 11; level = 2},/turf/simulated/floor{dir = 6; icon_state = "whitegreen"},/area/toxins/xenobiology/xenoflora) "chN" = (/turf/simulated/floor,/area/toxins/xenobiology/xenoflora) @@ -5828,7 +5828,7 @@ "cid" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cie" = (/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=1-Storage"; location = "7-Sleeper"},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"},/area/mine/laborcamp) "cif" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) -"cig" = (/obj/machinery/power/apc{dir = 4; name = "Engineering Maintenance APC"; pixel_x = 27; pixel_y = 2},/obj/structure/disposalpipe/segment,/obj/structure/cable,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/plating,/area/maintenance/aft) +"cig" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/apmaint) "cih" = (/obj/structure/table,/obj/machinery/cell_charger{pixel_y = 5},/obj/machinery/status_display{layer = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plating,/area/storage/tech) "cii" = (/obj/machinery/light/small,/turf/simulated/floor/plating,/area/storage/tech) "cij" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/storage/toolbox/electrical{pixel_x = 1; pixel_y = -1},/obj/item/clothing/gloves/yellow,/obj/item/device/t_scanner,/obj/item/clothing/glasses/meson,/obj/item/device/multitool,/turf/simulated/floor/plating,/area/storage/tech) @@ -5836,7 +5836,7 @@ "cil" = (/obj/machinery/vending/assist,/turf/simulated/floor/plating,/area/storage/tech) "cim" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor{dir = 8; icon_state = "cautioncorner"},/area/hallway/primary/aft) "cin" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/pump,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor{icon_state = "arrival"; dir = 8},/area/hallway/primary/aft) -"cio" = (/obj/machinery/atmospherics/pipe/manifold/hidden/cyan{dir = 1; level = 2},/obj/machinery/meter,/turf/simulated/wall/r_wall,/area) +"cio" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/engine/controlroom) "cip" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal{dir = 4},/turf/simulated/floor,/area/engine/controlroom) "ciq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor,/area/engine/controlroom) "cir" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor,/area/engine/controlroom) @@ -5876,20 +5876,20 @@ "ciZ" = (/obj/machinery/power/apc{dir = 8; name = "Aft Starboard Solar APC"; pixel_x = -26; pixel_y = 3},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/solar/starboard) "cja" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating,/area/solar/starboard) "cjb" = (/obj/machinery/power/smes{charge = 0},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/solar/starboard) -"cjc" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area) +"cjc" = (/turf/simulated/wall,/area/bridge/meeting_room) "cjd" = (/obj/item/clothing/mask/cigarette,/turf/simulated/floor/plating/airless,/area/toxins/test_area) "cje" = (/obj/machinery/light/small,/turf/simulated/floor/plating/airless,/area/toxins/test_area) -"cjf" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/aft) -"cjg" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/aft) +"cjf" = (/turf/simulated/floor/plating,/area/maintenance/apmaint) +"cjg" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/apmaint) "cjh" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/turf/simulated/floor{dir = 8; icon_state = "cautioncorner"},/area/hallway/primary/aft) "cji" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/pump,/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor{icon_state = "arrival"; dir = 8},/area/hallway/primary/aft) -"cjj" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 9; level = 2},/turf/simulated/wall/r_wall,/area) +"cjj" = (/turf/simulated/wall/r_wall,/area/blueshield) "cjk" = (/obj/machinery/camera{c_tag = "Atmospherics Access"; dir = 4; network = list("SS13")},/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6; level = 1},/obj/item/device/radio/intercom{freerange = 0; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -30},/turf/simulated/floor,/area/engine/controlroom) "cjl" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/engine/controlroom) "cjm" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/drone_fabricator,/turf/simulated/floor,/area/engine/controlroom) "cjn" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor,/area/engine/controlroom) "cjo" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/computer/drone_control,/turf/simulated/floor,/area/engine/controlroom) -"cjp" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/wall/r_wall,/area) +"cjp" = (/turf/simulated/wall/r_wall,/area/storage/tech) "cjq" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/electrical{pixel_y = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/item/device/radio/intercom{freerange = 0; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -30},/turf/simulated/floor{icon_state = "dark"},/area/construction) "cjr" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical{pixel_y = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10; initialize_directions = 10; level = 1},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor{icon_state = "dark"},/area/construction) "cjs" = (/obj/structure/table,/obj/item/device/multitool,/turf/simulated/floor{icon_state = "dark"},/area/construction) @@ -5911,7 +5911,7 @@ "cjI" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) "cjJ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) "cjK" = (/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) -"cjL" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/obj/machinery/light,/turf/simulated/floor/plating,/area/toxins/xenobiology/xenoflora) +"cjL" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/toxins/xenobiology/xenoflora) "cjM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/toxins/xenobiology/xenoflora) "cjN" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor,/area/toxins/xenobiology/xenoflora) "cjO" = (/obj/structure/table,/obj/item/clothing/gloves/color/latex,/turf/simulated/floor,/area/toxins/xenobiology/xenoflora) @@ -5921,8 +5921,8 @@ "cjS" = (/obj/structure/stool,/obj/machinery/camera{c_tag = "Aft Starboard Solar Control"; dir = 4; network = list("SS13")},/turf/simulated/floor/plating,/area/solar/starboard) "cjT" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plating,/area/solar/starboard) "cjU" = (/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/solar/starboard) -"cjV" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area) -"cjW" = (/obj/effect/decal/warning_stripes/west,/turf/simulated/floor/engine,/area) +"cjV" = (/turf/simulated/wall/r_wall,/area/crew_quarters/captain) +"cjW" = (/turf/simulated/wall/r_wall,/area/construction) "cjX" = (/obj/structure/spacepoddoor,/turf/simulated/floor/engine,/area/engine/mechanic_workshop) "cjY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/camera{c_tag = "Mechanic's Workshop West"; dir = 2; network = list("SS13")},/turf/simulated/floor/engine,/area/engine/mechanic_workshop) "cjZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/light{dir = 1},/turf/simulated/floor/engine,/area/engine/mechanic_workshop) @@ -5950,10 +5950,10 @@ "ckv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/hologram/holopad,/turf/simulated/floor{dir = 4; icon_state = "yellowcorner"},/area/hallway/primary/aft) "ckw" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor,/area/hallway/primary/aft) "ckx" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/scrubber,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor{dir = 8; icon_state = "escape"},/area/hallway/primary/aft) -"cky" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/machinery/meter,/turf/simulated/wall/r_wall,/area) +"cky" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/construction) "ckz" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access_txt = "0"; req_one_access_txt = "11;24"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9; level = 1},/turf/simulated/floor,/area/engine/controlroom) -"ckA" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/wall/r_wall,/area) -"ckB" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area) +"ckA" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/construction) +"ckB" = (/turf/simulated/wall/r_wall,/area/maintenance/incinerator) "ckC" = (/obj/machinery/iv_drip,/obj/machinery/light{dir = 8},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "ckD" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "ckE" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) @@ -5964,8 +5964,8 @@ "ckJ" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; external_pressure_bound = 101; on = 1; pressure_checks = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "ckK" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "ckL" = (/obj/machinery/iv_drip,/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) -"ckM" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/door/airlock/maintenance,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/asmaint) -"ckN" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/door/airlock/maintenance,/turf/simulated/floor/plating,/area/maintenance/asmaint) +"ckM" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/asmaint) +"ckN" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/asmaint) "ckO" = (/obj/machinery/door/window/eastright{base_state = "right"; dir = 1; icon_state = "right"; name = "Xenoflora Containment"; req_access_txt = "47"},/turf/simulated/floor,/area/toxins/xenobiology/xenoflora_storage) "ckP" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor,/area/toxins/xenobiology/xenoflora_storage) "ckQ" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "xeno_airlock_control"; name = "Xenobiology Access Button"; pixel_x = -24; pixel_y = 0; req_access_txt = "55"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/research{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "xeno_airlock_exterior"; locked = 1; name = "Xenobiology External Airlock"; req_access_txt = "55"},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) @@ -5999,14 +5999,14 @@ "cls" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/hallway/primary/aft) "clt" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor,/area/hallway/primary/aft) "clu" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/scrubber,/obj/machinery/camera{c_tag = "Aft Primary Hallway 2"; dir = 8; network = list("SS13"); pixel_x = 0; pixel_y = -22},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "escape"},/area/hallway/primary/aft) -"clv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/structure/sign/securearea,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area) +"clv" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/apmaint) "clw" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor,/area/engine/break_room) "clx" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/recharge_station,/turf/simulated/floor,/area/engine/break_room) "cly" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/newscaster{pixel_y = 32},/obj/machinery/computer/station_alert,/turf/simulated/floor,/area/engine/break_room) "clz" = (/obj/machinery/computer/arcade,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor,/area/engine/break_room) "clA" = (/obj/structure/table,/obj/machinery/media/receiver/boombox,/turf/simulated/floor,/area/engine/break_room) "clB" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/table,/turf/simulated/floor,/area/engine/break_room) -"clC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/wall/r_wall,/area) +"clC" = (/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/storage/tech) "clD" = (/obj/machinery/computer/general_air_control{frequency = 1441; name = "Tank Monitor"; sensors = list("n2_sensor" = "Nitrogen", "o2_sensor" = "Oxygen", "co2_sensor" = "Carbon Dioxide", "tox_sensor" = "Toxins", "n2o_sensor" = "Nitrous Oxide", "waste_sensor" = "Gas Mix Tank")},/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/turf/simulated/floor,/area/atmos/control) "clE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/camera{c_tag = "Atmospherics Control Room"; network = list("SS13")},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/apc{dir = 1; name = "Atmospherics Control APC"; pixel_y = 26},/obj/structure/table,/obj/item/weapon/book/manual/atmospipes,/obj/item/device/multitool{pixel_x = 5},/turf/simulated/floor,/area/atmos/control) "clF" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/computer/general_air_control{frequency = 1443; level = 3; name = "Distribution and Waste Monitor"; sensors = list("mair_in_meter" = "Mixed Air In", "air_sensor" = "Mixed Air Supply Tank", "mair_out_meter" = "Mixed Air Out", "dloop_atm_meter" = "Distribution Loop", "wloop_atm_meter" = "Waste Loop")},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor,/area/atmos/control) @@ -6037,7 +6037,7 @@ "cme" = (/obj/machinery/light,/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = -30},/turf/simulated/floor{dir = 10; icon_state = "whitegreen"},/area/toxins/xenobiology/xenoflora) "cmf" = (/obj/structure/reagent_dispensers/watertank,/obj/item/weapon/reagent_containers/glass/bucket,/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor{dir = 6; icon_state = "whitegreen"},/area/toxins/xenobiology/xenoflora) "cmg" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "solar_xeno_inner"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plating,/area/solar/starboard) -"cmh" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area) +"cmh" = (/obj/structure/sign/directions/evac{dir = 4},/obj/structure/sign/directions/medical{dir = 4; pixel_y = 7},/obj/structure/sign/directions/science{dir = 4},/turf/simulated/wall,/area/crew_quarters/bar) "cmi" = (/obj/structure/spacepoddoor,/obj/machinery/door/poddoor/three_tile_ver{id = "mechpodbay"; layer = 3.1; req_access_txt = "70"},/turf/simulated/floor/engine,/area/engine/mechanic_workshop) "cmj" = (/obj/machinery/door_control{desc = "A remote control-switch for the pod doors."; id = "mechpodbay"; name = "Pod Door Control"; pixel_x = 0; pixel_y = -24; req_access_txt = "70"},/turf/simulated/floor/engine,/area/engine/mechanic_workshop) "cmk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/engine,/area/engine/mechanic_workshop) @@ -6061,7 +6061,7 @@ "cmC" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/primary/aft) "cmD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor,/area/hallway/primary/aft) "cmE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"cmF" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area) +"cmF" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/grille,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/storage/tech) "cmG" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor,/area/engine/break_room) "cmH" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor{dir = 1; icon_state = "caution"},/area/engine/break_room) "cmI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/table,/obj/machinery/cell_charger,/obj/machinery/camera{c_tag = "Engineering Foyer"; network = list("SS13")},/obj/structure/noticeboard{pixel_y = 28},/turf/simulated/floor{icon_state = "caution"; dir = 5},/area/engine/break_room) @@ -6074,7 +6074,7 @@ "cmP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/stool/bed/chair/office/dark{dir = 1},/turf/simulated/floor,/area/atmos/control) "cmQ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/computer/atmos_alert,/turf/simulated/floor,/area/atmos/control) "cmR" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint) -"cmS" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/wall,/area) +"cmS" = (/obj/structure/sign/double/barsign,/turf/simulated/wall,/area/crew_quarters/bar) "cmT" = (/obj/structure/closet/secure_closet/medical3,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "cmU" = (/obj/structure/table,/obj/item/weapon/retractor,/obj/item/weapon/cautery,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "cmV" = (/obj/structure/table,/obj/item/weapon/retractor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/item/weapon/cautery,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) @@ -6084,14 +6084,14 @@ "cmZ" = (/obj/structure/sign/securearea{pixel_x = -32; pixel_y = 0},/obj/machinery/shower{tag = "icon-shower (EAST)"; icon_state = "shower"; dir = 4},/turf/simulated/floor{dir = 8; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/toxins/xenobiology) "cna" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) "cnb" = (/obj/structure/closet/l3closet/scientist,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 4; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/toxins/xenobiology) -"cnc" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area) -"cnd" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area) -"cne" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area) +"cnc" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/hydroponics) +"cnd" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/chapel/main) +"cne" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/chapel/main) "cnf" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "solar_xeno_pump"; tag_exterior_door = "solar_xeno_outer"; frequency = 1379; id_tag = "solar_xeno_airlock"; tag_interior_door = "solar_xeno_inner"; pixel_x = 25; req_access_txt = "13"; tag_chamber_sensor = "solar_xeno_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "solar_xeno_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "solar_xeno_pump"},/turf/simulated/floor/plating,/area/solar/starboard) "cng" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/aft) "cnh" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{icon_state = "door_locked"; locked = 1; name = "Assembly Line Maintenance"; req_access_txt = "32"},/turf/simulated/floor/plating,/area/assembly/assembly_line) "cni" = (/obj/machinery/door/window/southleft{base_state = "left"; dir = 2; icon_state = "left"; name = "Assembly Line Delivery"; req_access_txt = "32"},/turf/simulated/floor{icon_state = "delivery"},/area/assembly/assembly_line) -"cnj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area) +"cnj" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/storage/tech) "cnk" = (/obj/structure/disposalpipe/segment,/obj/machinery/light{dir = 8},/turf/simulated/floor{dir = 1; icon_state = "yellowcorner"},/area/hallway/primary/aft) "cnl" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor,/area/hallway/primary/aft) "cnm" = (/obj/structure/disposalpipe/sortjunction{dir = 2; icon_state = "pipe-j2s"; sortType = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor,/area/hallway/primary/aft) @@ -6124,7 +6124,7 @@ "cnN" = (/obj/structure/disposalpipe/trunk{dir = 4},/obj/structure/disposaloutlet,/turf/simulated/floor/engine,/area/toxins/xenobiology) "cnO" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/engine,/area/toxins/xenobiology) "cnP" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/engine,/area/toxins/xenobiology) -"cnQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "xenobio3"; name = "Containment Blast Doors"; opacity = 0},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area) +"cnQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/chapel/main) "cnR" = (/obj/machinery/disposal,/obj/structure/window/reinforced,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/toxins/xenobiology) "cnS" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) "cnT" = (/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) @@ -6135,7 +6135,7 @@ "cnY" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "solar_xeno_outer"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "10;13"},/turf/simulated/floor/plating,/area/solar/starboard) "cnZ" = (/obj/structure/lattice,/obj/structure/grille{density = 0; icon_state = "brokengrille"},/turf/space,/area) "coa" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating,/area/maintenance/aft) -"cob" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area) +"cob" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/storage/tech) "coc" = (/obj/item/weapon/table_parts,/turf/simulated/floor{icon_state = "floorgrime"},/area/assembly/assembly_line) "cod" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/assembly/assembly_line) "coe" = (/obj/item/weapon/camera_assembly,/turf/simulated/floor,/area/assembly/assembly_line) @@ -6155,7 +6155,7 @@ "cos" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor,/area/hallway/primary/aft) "cot" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/hallway/primary/aft) "cou" = (/obj/machinery/vending/cola,/turf/simulated/floor{icon_state = "arrival"; dir = 4},/area/hallway/primary/aft) -"cov" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/turf/simulated/floor/plating,/area) +"cov" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor/plating,/area/maintenance/incinerator) "cow" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/weapon/storage/belt/utility,/turf/simulated/floor,/area/engine/break_room) "cox" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/engine/break_room) "coy" = (/turf/simulated/floor,/area/engine/break_room) @@ -6171,10 +6171,10 @@ "coI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor/plating,/area/maintenance/asmaint) "coJ" = (/obj/machinery/shower{tag = "icon-shower (EAST)"; icon_state = "shower"; dir = 4},/obj/structure/sign/securearea{pixel_x = -32; pixel_y = 0},/turf/simulated/floor{dir = 8; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/medical/virology) "coK" = (/obj/structure/closet/l3closet,/obj/item/clothing/mask/gas,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor{dir = 4; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/medical/virology) -"coL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area) -"coM" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area) -"coN" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area) -"coO" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/wall/r_wall,/area) +"coL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/chapel/main) +"coM" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "heads_meeting"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/bridge/meeting_room) +"coN" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "heads_meeting"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/bridge/meeting_room) +"coO" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "heads_meeting"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/bridge/meeting_room) "coP" = (/turf/simulated/floor/engine,/area/toxins/xenobiology) "coQ" = (/mob/living/carbon/slime,/turf/simulated/floor/engine,/area/toxins/xenobiology) "coR" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "xenobio3"; name = "Containment Blast Doors"; opacity = 0},/obj/machinery/door/window/northleft{base_state = "right"; dir = 8; icon_state = "right"; name = "Containment Pen"; req_access_txt = "55"},/turf/simulated/floor/engine,/area/toxins/xenobiology) @@ -6184,7 +6184,7 @@ "coV" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "xeno_airlock_control"; name = "Xenobiology Access Button"; pixel_x = -28; pixel_y = 8; req_access_txt = "55"},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/research{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "xeno_airlock_interior"; locked = 1; name = "Xenobiology Internal Airlock"; req_access_txt = "55"},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) "coW" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "solar_xeno_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = "13"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk3"; icon_state = "catwalk3"},/area/solar/starboard) "coX" = (/turf/space,/area/xenos_station/southwest) -"coY" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area) +"coY" = (/turf/simulated/wall,/area/maintenance/incinerator) "coZ" = (/obj/item/stack/cable_coil,/turf/simulated/floor{icon_state = "floorgrime"},/area/assembly/assembly_line) "cpa" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor{icon_state = "floorgrime"},/area/assembly/assembly_line) "cpb" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor,/area/assembly/assembly_line) @@ -6231,7 +6231,7 @@ "cpQ" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/medical,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/camera{c_tag = "Virology Isolation 2"; dir = 2; network = list("SS13")},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cpR" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/light{dir = 1; on = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cpS" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/medical,/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/camera{c_tag = "Virology Isolation 3"; dir = 2; network = list("SS13")},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cpT" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "xenobio3"; name = "Containment Blast Doors"; opacity = 0},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area) +"cpT" = (/turf/simulated/wall/r_wall,/area/medical/chemistry) "cpU" = (/obj/structure/table/reinforced,/obj/machinery/door_control{id = "xenobio3"; name = "Containment Blast Doors"; pixel_x = 0; pixel_y = 4; req_access_txt = "55"},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/toxins/xenobiology) "cpV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) "cpW" = (/obj/machinery/requests_console{department = "Science"; departmentType = 2; name = "Science Requests Console"; pixel_x = 0; pixel_y = 30},/obj/machinery/camera{c_tag = "Xenobiology Module North"; dir = 2; network = list("Research","SS13"); pixel_x = 0},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) @@ -6248,7 +6248,7 @@ "cqh" = (/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor{icon_state = "floorgrime"},/area/assembly/assembly_line) "cqi" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "floorgrime"},/area/assembly/assembly_line) "cqj" = (/obj/item/weapon/paper,/turf/simulated/floor{icon_state = "floorgrime"},/area/assembly/assembly_line) -"cqk" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/barricade/wooden,/turf/simulated/floor/plating,/area) +"cqk" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/apmaint) "cql" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/hallway/primary/aft) "cqm" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/hallway/primary/aft) "cqn" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/light_switch{pixel_x = -23; pixel_y = 7},/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/tank/emergency_oxygen/engi,/obj/item/clothing/suit/storage/hazardvest,/obj/item/clothing/suit/storage/hazardvest,/obj/item/weapon/tank/emergency_oxygen/engi,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas{pixel_x = -3; pixel_y = -3},/turf/simulated/floor,/area/engine/break_room) @@ -6261,11 +6261,11 @@ "cqu" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/obj/structure/closet/secure_closet/atmos_personal,/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/atmos/control) "cqv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor,/area/atmos/control) "cqw" = (/obj/machinery/atmospherics/pipe/simple/visible/universal,/turf/simulated/floor/plating,/area/maintenance/asmaint) -"cqx" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/wall/r_wall,/area) +"cqx" = (/turf/simulated/wall,/area/medical/reception) "cqy" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/turf/simulated/wall/r_wall,/area/medical/virology) "cqz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "viro_airlock_interior"; locked = 1; name = "Virology Internal Airlock"; req_access_txt = "5"},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "viro_airlock_control"; name = "Virology Access Button"; pixel_x = -28; pixel_y = 8; req_access_txt = "5"},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cqA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/medical/virology) -"cqB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area) +"cqB" = (/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"},/turf/simulated/wall,/area/medical/reception) "cqC" = (/obj/structure/closet/secure_closet/personal/patient,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/power/apc{dir = 8; name = "Virology APC"; pixel_x = -25; pixel_y = 3},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/virology) "cqD" = (/obj/structure/closet/secure_closet/personal/patient,/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/virology) "cqE" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/medical/virology) @@ -6287,20 +6287,20 @@ "cqU" = (/obj/machinery/constructable_frame/machine_frame,/turf/simulated/floor{icon_state = "floorgrime"},/area/assembly/assembly_line) "cqV" = (/turf/simulated/floor/plating{desc = "
There is some old writing on this floor. You are barely able to read out a few lines from a tangled scribble.

In a chamber a great mirror lies, cut away it solemn cries. Travel bold as thou might, piercing vastness as a kite.

HONK!
"; name = "Old Note #6"},/area/assembly/assembly_line) "cqW" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/turf/simulated/floor/plating,/area/assembly/assembly_line) -"cqX" = (/obj/structure/table/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/barricade/wooden,/turf/simulated/floor{icon_state = "floorgrime"},/area) +"cqX" = (/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/cable,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/storage/tech) "cqY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "yellowcorner"},/area/hallway/primary/aft) "cqZ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/hallway/primary/aft) "cra" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=AIE"; location = "AftH"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/hallway/primary/aft) "crb" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/hallway/primary/aft) -"crc" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/turf/simulated/wall,/area) +"crc" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"},/turf/simulated/wall/r_wall,/area/storage/tech) "crd" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/alarm{dir = 4; pixel_x = -23; pixel_y = 0},/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = 20},/turf/simulated/floor,/area/engine/break_room) "cre" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor,/area/engine/break_room) "crf" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/regular{pixel_x = -2; pixel_y = 4},/turf/simulated/floor,/area/engine/break_room) "crg" = (/obj/effect/landmark/start{name = "Station Engineer"},/obj/structure/stool/bed/chair/comfy/black{dir = 8},/turf/simulated/floor,/area/engine/break_room) "crh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/flora/kirbyplants,/turf/simulated/floor,/area/engine/break_room) -"cri" = (/obj/machinery/door/airlock/atmos{name = "Atmospherics"; req_access_txt = "24"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/atmos) -"crj" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple,/turf/simulated/wall/r_wall,/area) -"crk" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan,/turf/simulated/wall/r_wall,/area) +"cri" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall{desc = "A specially coated wall that resists temperatures for Science"; max_temperature = 1e+009; name = "Coated Reinforced Wall"},/area/maintenance/incinerator) +"crj" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/wall/r_wall{desc = "A specially coated wall that resists temperatures for Science"; max_temperature = 1e+009; name = "Coated Reinforced Wall"},/area/maintenance/incinerator) +"crk" = (/obj/structure/sign/nosmoking_1,/turf/simulated/wall,/area/medical/reception) "crl" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/embedded_controller/radio/airlock/access_controller{id_tag = "viro_airlock_control"; name = "Virology Access Console"; pixel_x = 8; pixel_y = 22; tag_exterior_door = "viro_airlock_exterior"; tag_interior_door = "viro_airlock_interior"},/turf/simulated/floor{dir = 9; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTHEAST)"},/area/medical/virology) "crm" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/sign/biohazard{pixel_x = 32},/obj/machinery/door_control{id = "Biohazard_viro"; name = "Emergency Virology Entrance Quarantine"; pixel_x = 0; pixel_y = 25; req_access_txt = "39"},/turf/simulated/floor{tag = "icon-warnwhite (NORTHEAST)"; icon_state = "warnwhite"; dir = 5},/area/medical/virology) "crn" = (/obj/structure/closet/secure_closet/personal/patient,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/virology) @@ -6309,7 +6309,7 @@ "crq" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/medical/virology) "crr" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/medical/virology) "crs" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/medical/virology) -"crt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "xenobio2"; name = "Containment Blast Doors"; opacity = 0},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area) +"crt" = (/turf/simulated/wall,/area/medical/exam_room) "cru" = (/obj/machinery/disposal,/obj/structure/window/reinforced,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/toxins/xenobiology) "crv" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) "crw" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) @@ -6333,7 +6333,7 @@ "crO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) "crP" = (/obj/machinery/light,/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) "crQ" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/structure/flora/kirbyplants,/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"crR" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area) +"crR" = (/obj/machinery/door/poddoor{id = "disvent"; name = "Incinerator Vent"},/turf/simulated/floor/engine/vacuum,/area/maintenance/incinerator) "crS" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/light,/obj/structure/table,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/item/weapon/storage/toolbox/mechanical,/obj/item/device/t_scanner,/turf/simulated/floor,/area/engine/break_room) "crT" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/engine/break_room) "crU" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/turf/simulated/floor,/area/engine/break_room) @@ -6356,7 +6356,7 @@ "csl" = (/obj/machinery/atmospherics/binary/volume_pump/on{dir = 8; name = "Air To Distro"},/obj/machinery/power/apc{dir = 1; name = "Atmospherics Distribution Loop APC"; pixel_y = 24},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor,/area/atmos/distribution) "csm" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 10; initialize_directions = 10; level = 2},/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/turf/simulated/floor,/area/atmos/distribution) "csn" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/turf/simulated/floor,/area/atmos/distribution) -"cso" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area) +"cso" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/wall/r_wall{desc = "A specially coated wall that resists temperatures for Science"; max_temperature = 1e+009; name = "Coated Reinforced Wall"},/area/maintenance/incinerator) "csp" = (/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/obj/machinery/atmospherics/unary/vent_pump{dir = 8; external_pressure_bound = 100; on = 1; pressure_checks = 1},/turf/simulated/floor{dir = 8; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/medical/virology) "csq" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "csr" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{dir = 4; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/medical/virology) @@ -6364,7 +6364,7 @@ "cst" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/virology) "csu" = (/obj/machinery/light{dir = 1; on = 1},/obj/machinery/hologram/holopad,/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/virology) "csv" = (/obj/structure/disposalpipe/trunk,/obj/machinery/disposal,/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/virology) -"csw" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area) +"csw" = (/turf/simulated/wall,/area/medical/morgue) "csx" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "xenobio2"; name = "Containment Blast Doors"; opacity = 0},/obj/machinery/door/window/northleft{base_state = "right"; dir = 8; icon_state = "right"; name = "Containment Pen"; req_access_txt = "55"},/turf/simulated/floor/engine,/area/toxins/xenobiology) "csy" = (/obj/structure/stool/bed/chair{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) "csz" = (/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/weapon/storage/box/beakers{pixel_x = -1; pixel_y = -1; pixel_x = 2; pixel_y = 2},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) @@ -6399,7 +6399,7 @@ "ctc" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/atmos/distribution) "ctd" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan{dir = 8; initialize_directions = 11; level = 2},/obj/machinery/meter,/turf/simulated/floor,/area/atmos/distribution) "cte" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; level = 2},/turf/simulated/floor,/area/atmos/distribution) -"ctf" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 10; initialize_directions = 10; level = 2},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 10; initialize_directions = 10; level = 2},/turf/simulated/floor/plating,/area) +"ctf" = (/obj/structure/sign/securearea,/turf/simulated/wall/r_wall,/area/storage/tech) "ctg" = (/obj/structure/grille,/turf/simulated/wall/r_wall,/area/atmos) "cth" = (/obj/machinery/light,/turf/simulated/floor{dir = 10; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTHEAST)"},/area/medical/virology) "cti" = (/obj/machinery/camera{c_tag = "Virology Access South"; dir = 1; network = list("SS13")},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/turf/simulated/floor{dir = 6; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTHEAST)"},/area/medical/virology) @@ -6409,7 +6409,7 @@ "ctm" = (/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = -28},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/virology) "ctn" = (/obj/machinery/atmospherics/unary/vent_pump{on = 1},/obj/machinery/light,/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/virology) "cto" = (/obj/structure/disposalpipe/segment,/obj/machinery/vending/medical,/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/virology) -"ctp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area) +"ctp" = (/turf/simulated/wall/r_wall,/area/medical/morgue) "ctq" = (/obj/structure/table/reinforced,/obj/machinery/door_control{id = "xenobio2"; name = "Containment Blast Doors"; pixel_x = 0; pixel_y = 4; req_access_txt = "55"},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/toxins/xenobiology) "ctr" = (/obj/structure/stool/bed/chair{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) "cts" = (/obj/structure/table,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/obj/item/weapon/reagent_containers/spray/cleaner,/obj/item/clothing/gloves/color/latex,/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) @@ -6456,7 +6456,7 @@ "cuh" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4; level = 2},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/atmos/distribution) "cui" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4; level = 2},/obj/machinery/atmospherics/binary/pump{dir = 0; name = "Air to Mix"; on = 0},/turf/simulated/floor,/area/atmos/distribution) "cuj" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/atmospherics/valve/digital{color = ""; dir = 4; name = "Gas Mix Outlet Valve"},/turf/simulated/floor{dir = 5; icon_state = "green"},/area/atmos/distribution) -"cuk" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4; level = 2},/obj/machinery/atmospherics/pipe/simple/visible/cyan{level = 2},/turf/simulated/floor/plating,/area) +"cuk" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/wall/r_wall,/area/construction) "cul" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4; level = 2},/turf/space,/area) "cum" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/structure/grille,/obj/machinery/meter,/turf/simulated/wall/r_wall,/area/atmos) "cun" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; external_pressure_bound = 0; frequency = 1441; icon_state = "in"; id_tag = "waste_out"; initialize_directions = 1; internal_pressure_bound = 4000; on = 1; pressure_checks = 2; pump_direction = 0},/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/atmos) @@ -6487,7 +6487,7 @@ "cuM" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = -32; pixel_y = 0},/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating,/area/maintenance/portsolar) "cuN" = (/obj/machinery/power/terminal{dir = 4},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/maintenance/portsolar) "cuO" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/smes{charge = 0},/turf/simulated/floor/plating,/area/maintenance/portsolar) -"cuP" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall/r_wall,/area) +"cuP" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/maintenance{name = "Incinerator Access"; req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/incinerator) "cuQ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/light/small{dir = 1},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/aft) "cuR" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating,/area/maintenance/aft) "cuS" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/aft) @@ -6507,7 +6507,7 @@ "cvg" = (/obj/machinery/atmospherics/pipe/manifold/visible/green{dir = 1; tag = "icon-manifold-g (NORTH)"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/atmos/distribution) "cvh" = (/obj/machinery/atmospherics/pipe/manifold/visible/green{dir = 4; tag = "icon-manifold-g (NORTH)"},/turf/simulated/floor,/area/atmos/distribution) "cvi" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "waste_in"; name = "Gas Mix Tank Control"; output_tag = "waste_out"; sensors = list("waste_sensor" = "Tank")},/turf/simulated/floor{icon_state = "green"; dir = 4},/area/atmos/distribution) -"cvj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/cyan{level = 2},/turf/simulated/floor/plating,/area) +"cvj" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/apmaint) "cvk" = (/obj/structure/grille,/obj/structure/window/plasmareinforced{dir = 4},/obj/structure/window/plasmareinforced{dir = 8},/obj/structure/window/plasmareinforced{explosion_resistance = 10},/obj/structure/window/plasmareinforced{dir = 1},/turf/simulated/floor/plating,/area/atmos) "cvl" = (/obj/machinery/air_sensor{frequency = 1441; id_tag = "waste_sensor"; output = 63},/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/atmos) "cvm" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/atmos) @@ -6522,7 +6522,7 @@ "cvv" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0; tag = "icon-alarm0 (EAST)"},/turf/simulated/floor{dir = 9; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTHEAST)"},/area/medical/virology/lab) "cvw" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 101.325; on = 1; pressure_checks = 1},/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/simulated/floor{tag = "icon-warnwhite (NORTHEAST)"; icon_state = "warnwhite"; dir = 5},/area/medical/virology/lab) "cvx" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area/medical/virology) -"cvy" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "xenobio1"; name = "Containment Blast Doors"; opacity = 0},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area) +"cvy" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/hallway/primary/starboard/east) "cvz" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) "cvA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) "cvB" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) @@ -6559,7 +6559,7 @@ "cwg" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/rig,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/rig,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor,/area/engine/hardsuitstorage) "cwh" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/rig,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/rig,/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor,/area/engine/hardsuitstorage) "cwi" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/plating,/area/engine/chiefs_office) -"cwj" = (/obj/machinery/keycard_auth{pixel_x = 0; pixel_y = 24},/obj/structure/table/reinforced,/obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/clothing/glasses/meson{pixel_y = 4},/obj/item/device/megaphone,/mob/living/simple_animal/parrot/Poly,/turf/simulated/floor{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) +"cwj" = (/obj/machinery/keycard_auth{pixel_x = 0; pixel_y = 24},/obj/structure/table/reinforced,/obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/obj/item/clothing/glasses/meson{pixel_y = 4},/obj/item/device/megaphone,/mob/living/simple_animal/parrot/Poly,/turf/simulated/floor{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) "cwk" = (/obj/machinery/requests_console{announcementConsole = 1; department = "Chief Engineer's Desk"; departmentType = 3; name = "Chief Engineer RC"; pixel_x = 0; pixel_y = 32},/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/photocopier,/turf/simulated/floor{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) "cwl" = (/obj/machinery/door_control{id = "atmos"; name = "Atmospherics Lockdown"; pixel_x = 10; pixel_y = 24; req_access_txt = "24"},/obj/machinery/door_control{desc = "A remote control-switch for the engineering security doors."; id = "Engineering"; name = "Engineering Lockdown"; pixel_x = -10; pixel_y = 24; req_access_txt = "10"},/obj/machinery/door_control{desc = "A remote control-switch for secure storage."; id = "Secure Storage"; name = "Engineering Secure Storage"; pixel_x = 0; pixel_y = 24; req_access_txt = "11"},/obj/machinery/light_switch{pixel_y = 38},/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 101; on = 1; pressure_checks = 1},/turf/simulated/floor{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) "cwm" = (/turf/simulated/floor{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) @@ -6636,15 +6636,15 @@ "cxF" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; level = 2},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/atmos/distribution) "cxG" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; level = 2},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/atmos/distribution) "cxH" = (/obj/machinery/atmospherics/pipe/simple/visible/green{level = 2},/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 4; level = 2},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/atmos/distribution) -"cxI" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/manifold/visible/cyan{dir = 4; initialize_directions = 11; level = 2},/turf/simulated/floor/plating,/area) +"cxI" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/storage/tech) "cxJ" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; external_pressure_bound = 100; on = 1; pressure_checks = 1},/turf/simulated/floor{dir = 8; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/medical/virology/lab) "cxK" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/obj/machinery/light_switch{pixel_x = -27},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/virology) "cxL" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/medical,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/virology) "cxM" = (/obj/machinery/light,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/virology) "cxN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/item/weapon/bedsheet/medical,/obj/structure/stool/bed,/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/virology) -"cxO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/sign/securearea,/turf/simulated/wall,/area) +"cxO" = (/turf/simulated/wall/r_wall,/area/assembly/robotics) "cxP" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "viro_lab2_airlock_interior"; locked = 1; name = "Virology Lab Internal Airlock"; req_access_txt = "39"},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "viro_lab2_airlock_control"; name = "Virology Lab Access Button"; pixel_x = 28; pixel_y = 8; req_access_txt = "39"},/turf/simulated/floor{icon_state = "white"},/area/medical/virology/lab) -"cxQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area) +"cxQ" = (/turf/simulated/wall/r_wall,/area/toxins/lab) "cxR" = (/obj/machinery/camera{c_tag = "Xenobiology Module South"; dir = 4; network = list("Research","SS13"); pixel_x = 0},/obj/structure/table/reinforced,/obj/machinery/door_control{id = "xenobio1"; name = "Containment Blast Doors"; pixel_x = 0; pixel_y = 4; req_access_txt = "55"},/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/toxins/xenobiology) "cxS" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) "cxT" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) @@ -6652,7 +6652,7 @@ "cxV" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) "cxW" = (/obj/machinery/light{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) "cxX" = (/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = 27},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) -"cxY" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area) +"cxY" = (/turf/simulated/wall/r_wall,/area/hallway/secondary/exit) "cxZ" = (/turf/simulated/floor/plating/airless,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk8"; icon_state = "catwalk8"},/area/solar/starboard) "cya" = (/turf/simulated/floor/plating/airless,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk3"; icon_state = "catwalk3"},/area/solar/port) "cyb" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/maintenance/aft) @@ -6681,8 +6681,8 @@ "cyy" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical{pixel_y = 5},/obj/item/device/radio,/obj/item/device/radio,/obj/item/device/radio,/obj/item/device/radio,/obj/item/weapon/storage/belt/utility,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor,/area/engine/equipmentstorage) "cyz" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor,/area/engine/equipmentstorage) "cyA" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor,/area/engine/equipmentstorage) -"cyB" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/item/weapon/cell/high,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor,/area/engine/equipmentstorage) -"cyC" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/wall/r_wall,/area) +"cyB" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/item/weapon/stock_parts/cell/high,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor,/area/engine/equipmentstorage) +"cyC" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/grille,/obj/structure/cable,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/storage/tech) "cyD" = (/obj/machinery/atmospherics/portables_connector{dir = 1; name = "Connector Port (Air Supply)"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor,/area/atmos) "cyE" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/binary/volume_pump/on{dir = 4; name = "External to Filter"},/turf/simulated/floor,/area/atmos) "cyF" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/floor,/area/atmos) @@ -6716,7 +6716,7 @@ "czh" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) "czi" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) "czj" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) -"czk" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area) +"czk" = (/turf/simulated/wall/r_wall,/area/engine/gravitygenerator) "czl" = (/turf/simulated/wall,/area/maintenance/engi_shuttle) "czm" = (/obj/machinery/door/airlock/maintenance{name = "Engineering Shuttle"; req_access_txt = "0"; req_one_access_txt = "10;24"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) "czn" = (/obj/machinery/computer/station_alert,/turf/simulated/floor,/area/engine/engineering) @@ -6736,7 +6736,7 @@ "czB" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/table,/obj/item/clothing/gloves/black,/obj/item/clothing/gloves/black,/obj/item/clothing/gloves/black,/obj/item/weapon/crowbar/large,/obj/item/weapon/storage/box/lights/mixed,/turf/simulated/floor,/area/engine/equipmentstorage) "czC" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor,/area/engine/equipmentstorage) "czD" = (/obj/structure/reagent_dispensers/fueltank,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5; level = 1},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor,/area/engine/equipmentstorage) -"czE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area) +"czE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/crew_quarters/captain) "czF" = (/obj/structure/closet/wardrobe/atmospherics_yellow,/obj/machinery/atmospherics/pipe/simple/visible/universal{dir = 4},/turf/simulated/floor,/area/atmos) "czG" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; level = 2},/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor,/area/atmos) "czH" = (/obj/machinery/atmospherics/binary/volume_pump/on{dir = 8; name = "Filter to External"},/turf/simulated/floor,/area/atmos) @@ -6764,7 +6764,7 @@ "cAd" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/medical/virology/lab) "cAe" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/virology/lab) "cAf" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/simulated/floor{icon_state = "white"},/area/medical/virology/lab) -"cAg" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area) +"cAg" = (/obj/structure/sign/chemistry,/turf/simulated/wall/r_wall,/area/medical/chemistry) "cAh" = (/obj/structure/stool/bed/chair,/turf/simulated/floor{icon_state = "hydrofloor"},/area/toxins/xenobiology) "cAi" = (/obj/machinery/door/window/southright{dir = 1; name = "Containment Pen"; req_access_txt = "55"},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/toxins/xenobiology) "cAj" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/table/reinforced,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door_control{id = "xenobio4"; name = "Containment Blast Doors"; pixel_x = 0; pixel_y = 4; req_access_txt = "55"},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/toxins/xenobiology) @@ -6783,20 +6783,20 @@ "cAw" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) "cAx" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) "cAy" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) -"cAz" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{name = "Engineering Maintenance"; req_access_txt = "10"; req_one_access_txt = null},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor,/area/engine/engineering) +"cAz" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{name = "Engineering Maintenance"; req_access_txt = "10"; req_one_access_txt = null},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor,/area/maintenance/engi_shuttle) "cAA" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/engine/engineering) -"cAB" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/wall/r_wall,/area) +"cAB" = (/turf/simulated/wall/r_wall,/area/engine/mechanic_workshop) "cAC" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/engine/chiefs_office) "cAD" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_command{name = "Chief Engineer"; req_access_txt = "56"},/turf/simulated/floor,/area/engine/chiefs_office) "cAE" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/cable,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/engine/chiefs_office) "cAF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/engine/chiefs_office) "cAG" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area) "cAH" = (/obj/machinery/door/firedoor/border_only{layer = 2.6; name = "\improper Firelock South"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access_txt = "10"; req_one_access_txt = null},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/engine/break_room) -"cAI" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/wall/r_wall,/area) +"cAI" = (/turf/simulated/wall/r_wall{desc = "A specially coated wall that resists temperatures for Science"; max_temperature = 1e+009; name = "Coated Reinforced Wall"},/area/engine/mechanic_workshop) "cAJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/cable,/turf/simulated/floor/plating,/area/engine/engineering) "cAK" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/cable,/turf/simulated/floor/plating,/area/engine/engineering) "cAL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/cable,/turf/simulated/floor/plating,/area/engine/engineering) -"cAM" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5; level = 1},/turf/simulated/wall/r_wall,/area) +"cAM" = (/turf/simulated/wall/r_wall,/area/assembly/chargebay) "cAN" = (/obj/structure/table,/obj/item/clothing/head/welding{pixel_x = 1; pixel_x = -5; pixel_y = 3},/obj/item/stack/sheet/glass{amount = 50},/obj/item/clothing/head/welding{pixel_x = 0; pixel_x = -5; pixel_y = 3},/obj/machinery/atmospherics/pipe/simple/visible/universal{dir = 4},/turf/simulated/floor,/area/atmos) "cAO" = (/obj/structure/table,/obj/item/stack/sheet/metal{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/weapon/wrench,/obj/item/device/pipe_painter,/obj/item/device/pipe_painter,/obj/item/device/pipe_freezer,/obj/item/device/pipe_freezer,/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 9},/turf/simulated/floor,/area/atmos) "cAP" = (/obj/structure/table,/obj/item/clothing/gloves/black,/obj/item/clothing/gloves/black,/obj/item/clothing/gloves/black,/obj/item/device/t_scanner,/obj/item/device/multitool{pixel_x = 5},/obj/item/device/radio/headset/headset_eng,/obj/item/weapon/cartridge/atmos,/obj/item/weapon/cartridge/atmos,/obj/item/device/t_scanner,/turf/simulated/floor,/area/atmos) @@ -6807,7 +6807,7 @@ "cAU" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 4; initialize_directions = 11; level = 2},/turf/simulated/floor,/area/atmos) "cAV" = (/obj/machinery/atmospherics/trinary/filter{density = 0; dir = 1; filter_type = 4; name = "Gas filter (N2O tank)"; on = 1},/turf/simulated/floor,/area/atmos) "cAW" = (/obj/machinery/atmospherics/pipe/simple/visible/green{dir = 4; level = 2},/turf/simulated/floor{icon_state = "escape"; dir = 6},/area/atmos) -"cAX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/green{dir = 4; level = 2},/obj/machinery/atmospherics/pipe/simple/visible/cyan{level = 2},/turf/simulated/floor/plating,/area) +"cAX" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/wall/r_wall,/area/construction) "cAY" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/visible/green{dir = 4; level = 2},/turf/space,/area) "cAZ" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 8; frequency = 1441; icon_state = "on"; id = "n2o_in"; on = 1; pixel_y = 1},/turf/simulated/floor/engine,/area/atmos) "cBa" = (/obj/structure/table,/obj/item/weapon/storage/box/syringes,/obj/item/weapon/storage/box/beakers,/obj/item/weapon/hand_labeler,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/light{dir = 8},/obj/machinery/light_switch{pixel_x = -27},/obj/machinery/embedded_controller/radio/airlock/access_controller{id_tag = "viro_lab_airlock_control"; name = "Virology Lab Access Console"; pixel_x = 8; pixel_y = 22; tag_exterior_door = "viro_lab_airlock_exterior"; tag_interior_door = "viro_lab_airlock_interior"},/turf/simulated/floor{icon_state = "white"},/area/medical/virology/lab) @@ -6824,7 +6824,7 @@ "cBl" = (/obj/structure/disposalpipe/junction,/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/unary/vent_pump{dir = 8; external_pressure_bound = 100; on = 1; pressure_checks = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/virology/lab) "cBm" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/virology/lab) "cBn" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology/lab) -"cBo" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area) +"cBo" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/assembly/chargebay) "cBp" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "xenobio4"; name = "Containment Blast Doors"; opacity = 0},/obj/machinery/computer/reconstitutor/animal,/turf/simulated/floor/engine,/area/toxins/xenobiology) "cBq" = (/obj/machinery/door/window/southright{name = "Containment Pen"; req_access_txt = "55"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "xenobio4"; name = "Containment Blast Doors"; opacity = 0},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/engine,/area/toxins/xenobiology) "cBr" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "xenobio4"; name = "Containment Blast Doors"; opacity = 0},/obj/structure/cable,/turf/simulated/floor/plating,/area/toxins/xenobiology) @@ -6838,7 +6838,7 @@ "cBz" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) "cBA" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/space_heater,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) "cBB" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/power/monitor{name = "Engine Power Monitoring Computer"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor,/area/engine/engineering) -"cBC" = (/obj/structure/table,/obj/item/clothing/glasses/welding,/obj/item/clothing/glasses/welding,/obj/item/clothing/glasses/welding,/obj/item/clothing/ears/earmuffs{pixel_x = -5; pixel_y = 6},/obj/item/clothing/ears/earmuffs{pixel_x = -5; pixel_y = 6},/obj/item/clothing/ears/earmuffs{pixel_x = -5; pixel_y = 6},/obj/item/weapon/storage/belt/utility,/obj/item/weapon/storage/belt/utility,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/item/weapon/cell/high,/turf/simulated/floor,/area/engine/engineering) +"cBC" = (/obj/structure/table,/obj/item/clothing/glasses/welding,/obj/item/clothing/glasses/welding,/obj/item/clothing/glasses/welding,/obj/item/clothing/ears/earmuffs{pixel_x = -5; pixel_y = 6},/obj/item/clothing/ears/earmuffs{pixel_x = -5; pixel_y = 6},/obj/item/clothing/ears/earmuffs{pixel_x = -5; pixel_y = 6},/obj/item/weapon/storage/belt/utility,/obj/item/weapon/storage/belt/utility,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/item/weapon/stock_parts/cell/high,/turf/simulated/floor,/area/engine/engineering) "cBD" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/structure/table,/obj/item/stack/sheet/mineral/plasma{amount = 30},/obj/item/device/pipe_painter,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor,/area/engine/engineering) "cBE" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/power/port_gen/pacman,/turf/simulated/floor,/area/engine/engineering) "cBF" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor,/area/engine/engineering) @@ -6853,8 +6853,8 @@ "cBO" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/machinery/light_switch{pixel_x = -27},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor,/area/engine/engineering) "cBP" = (/obj/machinery/power/terminal{dir = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/engine/engineering) "cBQ" = (/obj/machinery/power/smes{charge = 1e+006},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/engine/engineering) -"cBR" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area) -"cBS" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/wall/r_wall,/area) +"cBR" = (/obj/effect/decal/warning_stripes/west,/turf/simulated/floor/engine,/area/engine/mechanic_workshop) +"cBS" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "robotics"; name = "Robotics Lab Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/assembly/robotics) "cBT" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/rig/atmos,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/rig/atmos,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor,/area/atmos) "cBU" = (/obj/machinery/atmospherics/pipe/manifold/visible/purple{dir = 8},/turf/simulated/floor,/area/atmos) "cBV" = (/obj/machinery/atmospherics/binary/volume_pump/on{dir = 8; name = "Port to Filter"},/turf/simulated/floor,/area/atmos) @@ -6864,7 +6864,7 @@ "cBZ" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{level = 2},/obj/machinery/atmospherics/portables_connector{dir = 4},/turf/simulated/floor,/area/atmos) "cCa" = (/obj/machinery/atmospherics/pipe/simple/visible/green{level = 2},/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4; level = 2},/turf/simulated/floor,/area/atmos) "cCb" = (/obj/machinery/light{dir = 4},/obj/machinery/atmospherics/binary/volume_pump/on{dir = 8; name = "Space Loop Out"},/turf/simulated/floor,/area/atmos) -"cCc" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/cyan{level = 2},/turf/simulated/floor/plating,/area) +"cCc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/engine/controlroom) "cCd" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/visible{dir = 10},/turf/space,/area) "cCe" = (/obj/structure/table,/obj/item/weapon/storage/box/masks,/obj/item/weapon/storage/box/gloves,/obj/machinery/requests_console{department = "Virology"; departmentType = 1; name = "Virology Requests Console"; pixel_x = -30},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/item/device/antibody_scanner,/turf/simulated/floor{icon_state = "white"},/area/medical/virology/lab) "cCf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/virology/lab) @@ -6878,7 +6878,7 @@ "cCn" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/virology/lab) "cCo" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/medical/virology/lab) "cCp" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/medical/virology/lab) -"cCq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area) +"cCq" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "rdlab"; name = "Research and Development Lab Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/toxins/lab) "cCr" = (/obj/machinery/clonepod{biomass = 150},/turf/simulated/floor/engine,/area/toxins/xenobiology) "cCs" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/engine,/area/toxins/xenobiology) "cCt" = (/turf/simulated/floor/plating/airless,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk12"; icon_state = "catwalk12"},/area/solar/starboard) @@ -6899,7 +6899,7 @@ "cCI" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/door/airlock/glass_engineering{name = "Engine Room"; req_access_txt = "10"; req_one_access_txt = null},/turf/simulated/floor,/area/engine/engineering) "cCJ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor,/area/engine/engineering) "cCK" = (/obj/machinery/power/smes{charge = 1e+006},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/engine/engineering) -"cCL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area) +"cCL" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/engine/controlroom) "cCM" = (/turf/simulated/floor/plating,/area/engine/engineering) "cCN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plating,/area/engine/engineering) "cCO" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/rig/atmos,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/rig/atmos,/obj/machinery/light{dir = 8},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/atmos) @@ -6932,7 +6932,7 @@ "cDp" = (/obj/structure/table,/obj/item/weapon/storage/box/monkeycubes,/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "white"},/area/medical/virology/lab) "cDq" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = -28},/obj/machinery/light,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology/lab) "cDr" = (/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/camera{c_tag = "Virology Lab East"; dir = 1; network = list("SS13")},/turf/simulated/floor{icon_state = "white"},/area/medical/virology/lab) -"cDs" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area) +"cDs" = (/turf/simulated/wall/r_wall,/area/maintenance/asmaint2) "cDt" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/engine,/area/toxins/xenobiology) "cDu" = (/obj/machinery/light/small{dir = 8},/obj/structure/disposalpipe/segment,/turf/simulated/floor/engine,/area/toxins/xenobiology) "cDv" = (/obj/machinery/light/small{dir = 8},/obj/machinery/camera{c_tag = "Engineering Secure Storage North"; dir = 4; network = list("SS13")},/obj/machinery/shield_capacitor,/turf/simulated/floor/plating,/area/storage/secure) @@ -6944,16 +6944,16 @@ "cDB" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor,/area/engine/engineering) "cDC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/engine/engineering) "cDD" = (/obj/structure/closet/secure_closet/engineering_electrical,/turf/simulated/floor,/area/engine/engineering) -"cDE" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = 0; pixel_y = 0},/turf/simulated/wall/r_wall,/area) -"cDF" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Singularity"; layer = 2.8; name = "Singularity Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area) -"cDG" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Singularity"; layer = 2.8; name = "Singularity Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area) +"cDE" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/wall/r_wall,/area/engine/controlroom) +"cDF" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/wall/r_wall,/area/engine/break_room) +"cDG" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/turf/simulated/wall/r_wall,/area/engine/break_room) "cDH" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Singularity"; layer = 2.7; name = "Singularity Blast Doors"; opacity = 0},/obj/machinery/door/airlock/glass_engineering{name = "Engine Room"; req_access_txt = "10"; req_one_access_txt = null},/turf/simulated/floor/plating,/area/engine/engineering) -"cDI" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Singularity"; layer = 2.8; name = "Singularity Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area) -"cDJ" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Singularity"; layer = 2.8; name = "Singularity Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area) -"cDK" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = 0; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area) -"cDL" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = 0; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area) +"cDI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/atmos/control) +"cDJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/atmos/control) +"cDK" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/atmos/control) +"cDL" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/wall/r_wall,/area/atmos/control) "cDM" = (/obj/machinery/power/smes{charge = 1e+006},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/engine/engineering) -"cDN" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area) +"cDN" = (/turf/simulated/wall/r_wall,/area/atmos/control) "cDO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/engine/engineering) "cDP" = (/obj/machinery/camera{c_tag = "Atmospherics West"; dir = 4; network = list("SS13")},/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor,/area/atmos) "cDQ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor,/area/atmos) @@ -6963,9 +6963,9 @@ "cDU" = (/obj/machinery/air_sensor{frequency = 1441; id_tag = "tox_sensor"},/turf/simulated/floor/engine{carbon_dioxide = 0; name = "plasma floor"; nitrogen = 0; oxygen = 0; toxins = 70000},/area/atmos) "cDV" = (/obj/machinery/portable_atmospherics/canister/toxins,/turf/simulated/floor/engine{carbon_dioxide = 0; name = "plasma floor"; nitrogen = 0; oxygen = 0; toxins = 70000},/area/atmos) "cDW" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/engine{carbon_dioxide = 0; name = "plasma floor"; nitrogen = 0; oxygen = 0; toxins = 70000},/area/atmos) -"cDX" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area) -"cDY" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area) -"cDZ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area) +"cDX" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/engine/gravitygenerator) +"cDY" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/engine/gravitygenerator) +"cDZ" = (/obj/structure/sign/examroom,/turf/simulated/wall,/area/medical/exam_room) "cEa" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Living Quarters"},/turf/simulated/floor{icon_state = "white"},/area/medical/virology/lab) "cEb" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/medical/virology/lab) "cEc" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/medical/virology/lab) @@ -6983,7 +6983,7 @@ "cEo" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "dark"},/area/storage/secure) "cEp" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "dark"},/area/storage/secure) "cEq" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "dark"},/area/storage/secure) -"cEr" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor{id = "Secure Storage"; name = "Secure Storage Blast Doors"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/storage/secure) +"cEr" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor{id = "Secure Storage"; name = "Secure Storage Blast Doors"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/storage/secure) "cEs" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor,/area/engine/engineering) "cEt" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor,/area/engine/engineering) "cEu" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor,/area/engine/engineering) @@ -6997,7 +6997,7 @@ "cEC" = (/obj/structure/closet/radiation,/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/obj/machinery/light/small{dir = 8},/turf/simulated/floor{dir = 9; icon_state = "yellow"},/area/engine/engineering) "cED" = (/turf/simulated/floor{tag = "icon-warningcorner (WEST)"; icon_state = "warningcorner"; dir = 8},/area/engine/engineering) "cEE" = (/obj/machinery/camera{c_tag = "Engineering SMES"; dir = 8; network = list("SS13"); pixel_x = 0; pixel_y = 0},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/engine/engineering) -"cEF" = (/obj/machinery/light/small{dir = 1},/obj/structure/closet/firecloset,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/engine/break_room) +"cEF" = (/turf/simulated/wall,/area/assembly/robotics) "cEG" = (/obj/machinery/portable_atmospherics/scrubber,/turf/simulated/floor,/area/atmos) "cEH" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/portable_atmospherics/scrubber,/turf/simulated/floor,/area/atmos) "cEI" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/manifold/visible{dir = 8},/turf/simulated/floor,/area/atmos) @@ -7048,7 +7048,7 @@ "cFB" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0; tag = "icon-alarm0 (EAST)"},/turf/simulated/floor{icon_state = "white"},/area/medical/virology/lab) "cFC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor{icon_state = "white"},/area/medical/virology/lab) "cFD" = (/obj/structure/stool/bed,/obj/effect/landmark/start{name = "Virologist"},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor{icon_state = "white"},/area/medical/virology/lab) -"cFE" = (/turf/simulated/floor/plating/airless,/area/toxins/xenobiology) +"cFE" = (/turf/simulated/wall,/area/medical/research{name = "Research Division"}) "cFF" = (/turf/simulated/floor/plating/airless,/obj/structure/cable,/obj/machinery/power/tracker,/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk1"; icon_state = "catwalk1"},/area/solar/starboard) "cFG" = (/turf/simulated/wall/r_wall,/area/maintenance/engi_shuttle) "cFH" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "engineering_dock_pump"},/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 1379; id_tag = "engineering_dock_airlock"; pixel_x = -25; pixel_y = 0; req_access_txt = "0"; req_one_access_txt = "13;10;24"; tag_airpump = "engineering_dock_pump"; tag_chamber_sensor = "engineering_dock_sensor"; tag_exterior_door = "engineering_dock_outer"; tag_interior_door = "engineering_dock_inner"},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) @@ -7104,7 +7104,7 @@ "cGF" = (/obj/item/weapon/screwdriver,/turf/simulated/floor,/area/engine/engineering) "cGG" = (/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/engine/engineering) "cGH" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "engineering_east_inner"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "10;13"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/engine/engineering) -"cGI" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/wall,/area) +"cGI" = (/turf/simulated/wall/r_wall,/area/engine/break_room) "cGJ" = (/obj/machinery/power/apc{dir = 8; name = "Atmospherics APC"; pixel_x = -24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 6},/turf/simulated/floor,/area/atmos) "cGK" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/stool/bed/chair,/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/floor,/area/atmos) "cGL" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/floor,/area/atmos) @@ -7118,8 +7118,8 @@ "cGT" = (/obj/machinery/air_sensor{frequency = 1441; id_tag = "co2_sensor"},/turf/simulated/floor/engine{carbon_dioxide = 50000; name = "co2 floor"; nitrogen = 0; oxygen = 0},/area/atmos) "cGU" = (/obj/machinery/portable_atmospherics/canister/carbon_dioxide,/turf/simulated/floor/engine{carbon_dioxide = 50000; name = "co2 floor"; nitrogen = 0; oxygen = 0},/area/atmos) "cGV" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/engine{carbon_dioxide = 50000; name = "co2 floor"; nitrogen = 0; oxygen = 0},/area/atmos) -"cGW" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area) -"cGX" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area) +"cGW" = (/obj/structure/sign/securearea,/turf/simulated/wall,/area/medical/research{name = "Research Division"}) +"cGX" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/hallway/primary/central/sw) "cGY" = (/turf/space,/area/vox_station/southwest_solars) "cGZ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) "cHa" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "engineering_dock_outer"; locked = 1; name = "Engineering Dock Airlock"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) @@ -7156,14 +7156,14 @@ "cHF" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 8; frequency = 1441; icon_state = "on"; id = "co2_in"; on = 1; pixel_y = 1},/turf/simulated/floor/engine{carbon_dioxide = 50000; name = "co2 floor"; nitrogen = 0; oxygen = 0},/area/atmos) "cHG" = (/turf/space,/area/shuttle/constructionsite/station) "cHH" = (/turf/simulated/floor/plating,/area/storage/secure) -"cHI" = (/obj/structure/closet/crate,/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/rods{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/weapon/airlock_electronics,/obj/item/weapon/airlock_electronics,/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/storage/secure) +"cHI" = (/obj/structure/closet/crate,/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/rods{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/weapon/airlock_electronics,/obj/item/weapon/airlock_electronics,/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/storage/secure) "cHJ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "engineering_west_pump"; tag_exterior_door = "engineering_west_outer"; frequency = 1379; id_tag = "engineering_west_airlock"; tag_interior_door = "engineering_west_inner"; pixel_x = 25; req_access_txt = "10;13"; tag_chamber_sensor = "engineering_west_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "engineering_west_sensor"; pixel_x = 25; pixel_y = 12},/turf/simulated/floor/plating,/area/engine/engineering) -"cHK" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area) -"cHL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area) +"cHK" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/wall/r_wall,/area/atmos/control) +"cHL" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/atmos/control) "cHM" = (/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/engine/engineering) "cHN" = (/obj/item/weapon/wirecutters,/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/engine/engineering) "cHO" = (/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/engine/engineering) -"cHP" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area) +"cHP" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/engine/break_room) "cHQ" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "engineering_east_pump"; tag_exterior_door = "engineering_east_outer"; frequency = 1379; id_tag = "engineering_east_airlock"; tag_interior_door = "engineering_east_inner"; pixel_x = -25; req_access_txt = "10;13"; tag_chamber_sensor = "engineering_east_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "engineering_east_sensor"; pixel_x = -25; pixel_y = 12},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/engine/engineering) "cHR" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "engineering_east_pump"},/turf/simulated/floor/plating,/area/engine/engineering) "cHS" = (/obj/machinery/camera{c_tag = "Atmospherics South-West"; dir = 4; network = list("SS13")},/obj/machinery/light{dir = 8},/obj/structure/stool,/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor,/area/atmos) @@ -7177,10 +7177,10 @@ "cIa" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "engineering_west_outer"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "10;13"},/turf/simulated/floor/plating,/area/engine/engineering) "cIb" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plating/airless,/area/engine/engineering) "cIc" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering) -"cId" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area) -"cIe" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area) -"cIf" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area) -"cIg" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area) +"cId" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/assembly/assembly_line) +"cIe" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/assembly/assembly_line) +"cIf" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/assembly/assembly_line) +"cIg" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/assembly/assembly_line) "cIh" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plating/airless,/area/engine/engineering) "cIi" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "engineering_east_outer"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "10;13"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/engine/engineering) "cIj" = (/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 5},/turf/simulated/floor,/area/atmos) @@ -7190,18 +7190,18 @@ "cIn" = (/obj/machinery/atmospherics/trinary/filter{density = 0; dir = 4; filter_type = 1; name = "Gas filter (O2 tank)"; on = 1},/turf/simulated/floor,/area/atmos) "cIo" = (/obj/machinery/atmospherics/pipe/simple/visible/green{dir = 4; level = 2},/turf/simulated/floor,/area/atmos) "cIp" = (/obj/machinery/atmospherics/pipe/simple/visible/green{dir = 9; level = 2},/turf/simulated/floor,/area/atmos) -"cIq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 9; level = 2},/turf/simulated/floor/plating,/area) +"cIq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/aft) "cIr" = (/obj/structure/closet/radiation,/turf/simulated/floor/plating,/area/storage/secure) "cIs" = (/obj/machinery/the_singularitygen{anchored = 0},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/storage/secure) "cIt" = (/obj/machinery/power/port_gen/pacman,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/storage/secure) -"cIu" = (/obj/structure/grille,/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plating/airless,/area) +"cIu" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area/assembly/assembly_line) "cIv" = (/obj/item/weapon/extinguisher,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "engineering_west_airlock"; name = "exterior access button"; pixel_x = 20; pixel_y = 20; req_access_txt = "10;13"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering) "cIw" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/camera/emp_proof{c_tag = "Engineering Singularity North-West"; dir = 2; network = list("Singularity","SS13"); pixel_x = 20; pixel_y = 0},/turf/simulated/floor/plating/airless,/area/engine/engineering) "cIx" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering) "cIy" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering) "cIz" = (/obj/machinery/camera/emp_proof{c_tag = "Engineering Singularity North-East"; dir = 2; network = list("Singularity","SS13")},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering) "cIA" = (/obj/item/weapon/wrench,/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "engineering_east_airlock"; name = "exterior access button"; pixel_x = -20; pixel_y = 20; req_access_txt = "10;13"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering) -"cIB" = (/obj/structure/grille,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plating/airless,/area) +"cIB" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/turf/simulated/floor/plating,/area/engine/break_room) "cIC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/engine/engineering) "cID" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/computer/atmos_alert,/turf/simulated/floor,/area/atmos) "cIE" = (/obj/machinery/computer/security/engineering,/turf/simulated/floor{icon_state = "red"; dir = 10},/area/atmos) @@ -7214,28 +7214,28 @@ "cIL" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{level = 2},/turf/simulated/floor{icon_state = "arrival"; dir = 10},/area/atmos) "cIM" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1443; input_tag = "air_in"; name = "Mixed Air Supply Control"; output_tag = "air_out"; pressure_setting = 2000; sensors = list("air_sensor" = "Tank")},/turf/simulated/floor{icon_state = "arrival"},/area/atmos) "cIN" = (/obj/machinery/camera{c_tag = "Atmospherics South-East"; dir = 1; network = list("SS13")},/obj/machinery/atmospherics/valve/digital{name = "Mixed Air Outlet Valve"; openDuringInit = 1},/turf/simulated/floor{icon_state = "arrival"; dir = 6},/area/atmos) -"cIO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area) +"cIO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/aft) "cIP" = (/obj/machinery/floodlight,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/storage/secure) -"cIQ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/grille,/turf/simulated/floor/plating/airless,/area) +"cIQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/assembly/assembly_line) "cIR" = (/turf/simulated/floor/plating/airless,/area/engine/engineering) -"cIS" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area) -"cIT" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/green{dir = 6},/turf/simulated/floor/plating,/area) -"cIU" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/green{dir = 9},/turf/simulated/floor/plating,/area) -"cIV" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/yellow{level = 2},/turf/simulated/floor/plating,/area) -"cIW" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/plating,/area) -"cIX" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/green{level = 2},/turf/simulated/floor/plating,/area) -"cIY" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area) -"cIZ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/cyan{level = 2},/turf/simulated/floor/plating,/area) -"cJa" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area) +"cIS" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/barricade/wooden,/turf/simulated/floor/plating,/area/assembly/assembly_line) +"cIT" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/wall/r_wall,/area/atmos/control) +"cIU" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/assembly/assembly_line) +"cIV" = (/obj/structure/table/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/barricade/wooden,/turf/simulated/floor{icon_state = "floorgrime"},/area/assembly/assembly_line) +"cIW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/bridge/meeting_room) +"cIX" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/wall/r_wall,/area/atmos/control) +"cIY" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/wall/r_wall,/area/atmos/control) +"cIZ" = (/obj/machinery/door/airlock/atmos{name = "Atmospherics"; req_access_txt = "24"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/atmos/control) +"cJa" = (/turf/simulated/wall/r_wall,/area/atmos/distribution) "cJb" = (/turf/space,/area/xenos_station/southeast) "cJc" = (/obj/machinery/light/small{dir = 8},/obj/machinery/power/emitter,/turf/simulated/floor/plating,/area/storage/secure) "cJd" = (/obj/machinery/power/emitter,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/storage/secure) "cJe" = (/obj/machinery/floodlight,/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/storage/secure) -"cJf" = (/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating/airless,/area) +"cJf" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/wall/r_wall,/area/atmos) "cJg" = (/obj/machinery/power/emitter{anchored = 1; dir = 4; state = 2},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating/airless,/area/engine/engineering) "cJh" = (/obj/machinery/field_generator{anchored = 1; state = 2},/turf/simulated/floor/plating/airless,/area) "cJi" = (/obj/machinery/power/emitter{anchored = 1; dir = 8; state = 2},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating/airless,/area/engine/engineering) -"cJj" = (/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating/airless,/area) +"cJj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/atmos/distribution) "cJk" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/visible/green{level = 2},/turf/space,/area) "cJl" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/visible/yellow{level = 2},/turf/space,/area) "cJm" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/visible{dir = 5},/turf/space,/area) @@ -7246,7 +7246,7 @@ "cJr" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 4},/turf/space,/area) "cJs" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 9},/turf/space,/area) "cJt" = (/obj/machinery/power/emitter,/turf/simulated/floor/plating,/area/storage/secure) -"cJu" = (/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating/airless,/area) +"cJu" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple,/turf/simulated/wall/r_wall,/area/atmos/distribution) "cJv" = (/obj/item/device/multitool,/turf/simulated/floor/plating/airless,/area/engine/engineering) "cJw" = (/obj/item/weapon/wirecutters,/obj/structure/lattice,/turf/space,/area) "cJx" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/structure/grille,/obj/machinery/meter,/turf/simulated/wall/r_wall,/area/atmos) @@ -7254,10 +7254,10 @@ "cJz" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/structure/grille,/obj/machinery/meter{frequency = 1443; id = "mair_out_meter"; name = "Mixed Air Tank Out"},/turf/simulated/wall/r_wall,/area/atmos) "cJA" = (/obj/machinery/power/emitter,/obj/machinery/camera{c_tag = "Engineering Secure Storage South"; dir = 4; network = list("SS13")},/turf/simulated/floor/plating,/area/storage/secure) "cJB" = (/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/storage/secure) -"cJC" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/grille,/turf/simulated/floor/plating/airless,/area) -"cJD" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/grille,/turf/simulated/floor/plating/airless,/area) -"cJE" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/grille,/turf/simulated/floor/plating/airless,/area) -"cJF" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/grille,/turf/simulated/floor/plating/airless,/area) +"cJC" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan,/turf/simulated/wall/r_wall,/area/atmos/distribution) +"cJD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/atmos/distribution) +"cJE" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/aft) +"cJF" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/bridge/meeting_room) "cJG" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/engine/engineering) "cJH" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 1; frequency = 1441; icon_state = "on"; id = "n2_in"; on = 1},/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/atmos) "cJI" = (/obj/machinery/air_sensor{frequency = 1441; id_tag = "n2_sensor"},/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/atmos) @@ -7275,10 +7275,10 @@ "cJU" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/floor/engine{name = "o2 floor"; nitrogen = 0; oxygen = 100000},/area/atmos) "cJV" = (/turf/simulated/floor/engine{name = "air floor"; nitrogen = 10580; oxygen = 2644},/area/atmos) "cJW" = (/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/engine{name = "air floor"; nitrogen = 10580; oxygen = 2644},/area/atmos) -"cJX" = (/obj/machinery/light{dir = 8},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/grille,/turf/simulated/floor/plating/airless,/area) +"cJX" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/wall/r_wall,/area/atmos) "cJY" = (/obj/item/weapon/wrench,/turf/simulated/floor/plating/airless,/area) "cJZ" = (/obj/machinery/the_singularitygen{anchored = 1},/obj/effect/decal/warning_stripes/red/hollow,/turf/simulated/floor/plating/airless,/area) -"cKa" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/grille,/turf/simulated/floor/plating/airless,/area) +"cKa" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/atmos/distribution) "cKb" = (/obj/machinery/light/small,/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/atmos) "cKc" = (/obj/machinery/light/small,/turf/simulated/floor/engine{name = "o2 floor"; nitrogen = 0; oxygen = 100000},/area/atmos) "cKd" = (/obj/machinery/light/small,/turf/simulated/floor/engine{name = "air floor"; nitrogen = 10580; oxygen = 2644},/area/atmos) @@ -7291,19 +7291,19 @@ "cKk" = (/obj/structure/transit_tube/station{dir = 8; icon_state = "closed"},/obj/structure/transit_tube_pod,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plating,/area/engine/engineering) "cKl" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/engine/engineering) "cKm" = (/turf/space,/area/syndicate_station/southeast) -"cKn" = (/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating/airless,/area) +"cKn" = (/turf/simulated/wall/r_wall,/area/maintenance/aft) "cKo" = (/obj/machinery/power/emitter{anchored = 1; dir = 4; state = 2},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/camera/emp_proof{c_tag = "Engineering Singularity West"; dir = 4; network = list("Singularity","SS13")},/turf/simulated/floor/plating/airless,/area/engine/engineering) "cKp" = (/obj/item/weapon/screwdriver,/obj/structure/lattice,/turf/space,/area) "cKq" = (/obj/machinery/power/emitter{anchored = 1; dir = 8; state = 2},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/camera/emp_proof{c_tag = "Engineering Singularity East"; dir = 8; network = list("Singularity","SS13")},/turf/simulated/floor/plating/airless,/area/engine/engineering) -"cKr" = (/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating/airless,/area) +"cKr" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/hallway/primary/aft) "cKs" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/command{name = "MiniSat Access"; req_access_txt = "75"},/turf/simulated/floor,/area/engine/engineering) "cKt" = (/obj/structure/transit_tube{icon_state = "N-S"},/turf/simulated/floor/plating,/area/engine/engineering) "cKu" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/engine/engineering) -"cKv" = (/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating/airless,/area) -"cKw" = (/obj/structure/grille,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating/airless,/area) +"cKv" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 10; initialize_directions = 10; level = 2},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 10; initialize_directions = 10; level = 2},/turf/simulated/floor/plating,/area/atmos/distribution) +"cKw" = (/turf/simulated/wall/r_wall,/area/maintenance/portsolar) "cKx" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering) "cKy" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering) -"cKz" = (/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating/airless,/area) +"cKz" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/portsolar) "cKA" = (/obj/structure/closet/emcloset,/obj/machinery/light_switch{pixel_x = -27},/turf/simulated/floor,/area/engine/engineering) "cKB" = (/obj/machinery/light,/turf/simulated/floor,/area/engine/engineering) "cKC" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/engine/engineering) @@ -7370,7 +7370,7 @@ "cLL" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/aisat/entrance) "cLM" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/aisat/entrance) "cLN" = (/obj/machinery/computer/security/telescreen{desc = ""; dir = 1; layer = 4; name = "Mini Satellite Monitor"; network = list("MiniSat"); pixel_x = 0; pixel_y = -30},/turf/simulated/floor{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/aisat/entrance) -"cLO" = (/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/turretid{control_area = "\improper AI Satellite Antechamber"; name = "AI Antechamber Turret Control"; pixel_x = 0; pixel_y = -24; req_access = null; req_access_txt = "75"},/turf/simulated/floor{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/aisat/entrance) +"cLO" = (/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/turretid/stun{control_area = "\improper AI Satellite Antechamber"; name = "AI Antechamber Turret Control"; pixel_x = 0; pixel_y = -24; req_access_txt = "75"},/turf/simulated/floor{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/aisat/entrance) "cLP" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/sign/vacuum,/turf/simulated/wall,/area) "cLQ" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/aisat) "cLR" = (/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/aisat) @@ -7413,9 +7413,9 @@ "cMC" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/obj/structure/cable,/obj/machinery/power/apc{dir = 4; name = "AI Satellite Antechamber APC"; pixel_x = 25},/turf/simulated/floor{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/aisat_interior) "cMD" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/light/small{dir = 4},/obj/machinery/camera/motion{c_tag = "Mini Satellite Exterior North-West"; dir = 8; network = list("SS13","MiniSat")},/turf/simulated/floor/plating,/area/aisat) "cME" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/bot/floorbot{on = 0},/turf/simulated/floor{dir = 8; icon_state = "vault"; tag = "icon-vault (WEST)"},/area/turret_protected/aisat_interior) -"cMF" = (/obj/machinery/turret{dir = 1},/obj/machinery/ai_status_display{pixel_y = -32},/turf/simulated/floor{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/aisat_interior) +"cMF" = (/obj/machinery/ai_status_display{pixel_y = -32},/obj/machinery/porta_turret{dir = 1},/turf/simulated/floor{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/aisat_interior) "cMG" = (/obj/machinery/camera/motion{c_tag = "Mini Satellite Antechamber"; dir = 1; network = list("SS13","MiniSat")},/turf/simulated/floor{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/aisat_interior) -"cMH" = (/obj/machinery/turret{dir = 1},/obj/machinery/status_display{pixel_x = 0; pixel_y = -32},/turf/simulated/floor{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/aisat_interior) +"cMH" = (/obj/machinery/status_display{pixel_x = 0; pixel_y = -32},/obj/machinery/porta_turret{dir = 1},/turf/simulated/floor{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/aisat_interior) "cMI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/bot/cleanbot{on = 0},/turf/simulated/floor{dir = 8; icon_state = "vault"; tag = "icon-vault (WEST)"},/area/turret_protected/aisat_interior) "cMJ" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/light/small{dir = 8},/obj/machinery/camera/motion{c_tag = "Mini Satellite Exterior North-East"; dir = 4; network = list("SS13","MiniSat")},/turf/simulated/floor/plating,/area/aisat) "cMK" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/highsecurity{icon_state = "door_locked"; locked = 1; name = "AI Chamber"; req_access_txt = "16"},/turf/simulated/floor{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/ai) @@ -7428,9 +7428,9 @@ "cMR" = (/obj/structure/table/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/item/weapon/folder/white,/turf/simulated/floor{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/ai) "cMS" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 101.325; on = 1; pressure_checks = 1},/turf/simulated/floor{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/ai) "cMT" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/ai) -"cMU" = (/obj/machinery/turret{dir = 4},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) +"cMU" = (/obj/machinery/porta_turret{dir = 4},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "cMV" = (/obj/machinery/light,/obj/machinery/ai_slipper{icon_state = "motion0"},/obj/machinery/flasher{id = "AI"; pixel_x = 0; pixel_y = -21},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) -"cMW" = (/obj/machinery/turret{dir = 8},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) +"cMW" = (/obj/machinery/porta_turret{dir = 8},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "cMX" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/aisat) "cMY" = (/turf/simulated/wall,/area/turret_protected/ai) "cMZ" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/aisat) @@ -7440,7 +7440,7 @@ "cNd" = (/obj/effect/landmark{name = "tripai"},/obj/item/device/radio/intercom{anyai = 1; freerange = 1; listening = 0; name = "Custom Channel"; pixel_x = 0; pixel_y = 19},/obj/item/device/radio/intercom{anyai = 1; broadcasting = 0; freerange = 1; frequency = 1447; name = "Private Channel"; pixel_x = 0; pixel_y = -26},/obj/item/device/radio/intercom{anyai = 1; broadcasting = 0; freerange = 1; listening = 1; name = "Common Channel"; pixel_x = 27; pixel_y = -3},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "cNe" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/apc{aidisabled = 0; cell_type = 5000; dir = 1; name = "AI Core APC"; pixel_x = -5; pixel_y = 24},/turf/simulated/floor{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/ai) "cNf" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/door/window/southright{name = "AI Core Door"; req_access = null; req_access_txt = "16"},/turf/simulated/floor{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/ai) -"cNg" = (/obj/machinery/turretid{name = "AI Chamber Turret Control"; pixel_x = 5; pixel_y = 24; req_access = null; req_access_txt = "75"},/obj/machinery/flasher{id = "AI"; pixel_x = -6; pixel_y = 24},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/camera/motion{c_tag = "Mini Satellite AI Chamber South"; dir = 2; network = list("SS13","MiniSat")},/turf/simulated/floor{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/ai) +"cNg" = (/obj/machinery/turretid/lethal{check_synth = 1; name = "AI Chamber Turret Control"; pixel_x = 5; pixel_y = 24; req_access_txt = "75"},/obj/machinery/flasher{id = "AI"; pixel_x = -6; pixel_y = 24},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/camera/motion{c_tag = "Mini Satellite AI Chamber South"; dir = 2; network = list("SS13","MiniSat")},/turf/simulated/floor{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/ai) "cNh" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/space,/area) "cNi" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/ai_slipper{icon_state = "motion0"},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "cNj" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/aisat) @@ -7457,7 +7457,7 @@ "cNu" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/window/reinforced{dir = 4},/obj/machinery/light/small{dir = 4},/obj/machinery/camera/motion{c_tag = "Mini Satellite Exterior South-West"; dir = 8; network = list("SS13","MiniSat")},/turf/simulated/floor/plating,/area/aisat) "cNv" = (/obj/machinery/power/smes{charge = 5e+006},/obj/structure/cable,/turf/simulated/floor{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/ai) "cNw" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/light/small{dir = 8},/obj/machinery/camera/motion{c_tag = "Mini Satellite Exterior South-East"; dir = 4; network = list("SS13","MiniSat")},/turf/simulated/floor/plating,/area/aisat) -"cNx" = (/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/wall/r_wall,/area) +"cNx" = (/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) "cNy" = (/obj/structure/rack,/obj/item/weapon/storage/toolbox/electrical{pixel_x = -3; pixel_y = 3},/obj/item/weapon/storage/toolbox/mechanical{pixel_x = 0; pixel_y = 0},/obj/item/device/multitool,/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor{dir = 9; icon_state = "yellow"},/area/aisat/maintenance) "cNz" = (/obj/machinery/atmospherics/pipe/tank/air,/turf/simulated/floor{dir = 5; icon_state = "yellow"},/area/aisat/maintenance) "cNA" = (/obj/machinery/recharge_station,/turf/simulated/floor{dir = 9; icon_state = "yellow"},/area/aisat/maintenance) @@ -7647,7 +7647,7 @@ "cRc" = (/obj/effect/decal/cleanable/cobweb2,/turf/unsimulated/floor{name = "plating"},/area/prison/solitary) "cRd" = (/obj/structure/stool/bed,/turf/unsimulated/floor{icon_state = "floorscorched2"},/area/prison/solitary) "cRe" = (/obj/effect/decal/cleanable/blood,/turf/unsimulated/floor{name = "plating"},/area/prison/solitary) -"cRf" = (/obj/machinery/door_control{id = "alienshutters"; name = "Alien Blast Shutter Control"; pixel_x = -26; pixel_y = -2; req_access_txt = "0"},/obj/machinery/camera{c_tag = "Xeno Shuttle North"; dir = 4; indestructible = 1; network = list("Xeno")},/turf/simulated/floor/plating/airless,/area/xenos_station/start) +"cRf" = (/obj/machinery/camera{c_tag = "Xeno Shuttle West"; dir = 4; network = list("Xeno")},/turf/simulated/floor/plating/airless,/area/xenos_station/start) "cRg" = (/obj/machinery/computer/xenos_station,/turf/simulated/floor/plating/airless,/area/xenos_station/start) "cRh" = (/turf/simulated/floor/plating/airless,/area/xenos_station/start) "cRi" = (/turf/simulated/floor/holofloor{tag = "icon-carpet2-0 (EAST)"; icon_state = "carpet2-0"; dir = 4},/area/holodeck/source_theatre) @@ -7714,8 +7714,8 @@ "cSr" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/unsimulated/wall{tag = "icon-iron12"; icon_state = "iron12"},/area) "cSs" = (/turf/unsimulated/wall{tag = "icon-iron11"; icon_state = "iron11"},/area) "cSt" = (/turf/space/transit/north/shuttlespace_ns15,/area/shuttle/escape/transit) -"cSu" = (/obj/machinery/camera{c_tag = "Xeno Shuttle West"; dir = 4; indestructible = 1; network = list("Xeno")},/turf/simulated/floor/plating/airless,/area/xenos_station/start) -"cSv" = (/obj/machinery/camera{c_tag = "Xeno Shuttle East"; dir = 8; indestructible = 1; network = list("Xeno")},/turf/simulated/floor/plating/airless,/area/xenos_station/start) +"cSu" = (/obj/machinery/camera{c_tag = "Xeno Shuttle East"; dir = 8; network = list("Xeno")},/turf/simulated/floor/plating/airless,/area/xenos_station/start) +"cSv" = (/obj/machinery/camera{c_tag = "Xeno Shuttle South-West"; dir = 1; network = list("Xeno")},/obj/machinery/power/terminal{dir = 8},/turf/simulated/floor/greengrid/airless,/area/xenos_station/start) "cSw" = (/turf/simulated/floor/holofloor{tag = "icon-1 (NORTHEAST)"; icon_state = "1"; dir = 5},/area/holodeck/source_space) "cSx" = (/turf/simulated/floor/holofloor{tag = "icon-17 (NORTHEAST)"; icon_state = "17"; dir = 5},/area/holodeck/source_space) "cSy" = (/turf/simulated/floor/holofloor{tag = "icon-22 (NORTHEAST)"; icon_state = "22"; dir = 5},/area/holodeck/source_space) @@ -7788,7 +7788,7 @@ "cTN" = (/turf/unsimulated/beach/sand,/area/ninja/holding) "cTO" = (/obj/effect/overlay/palmtree_r,/obj/effect/overlay/coconut,/turf/unsimulated/beach/sand,/area/ninja/holding) "cTP" = (/obj/effect/overlay/palmtree_l,/turf/unsimulated/beach/sand,/area/ninja/holding) -"cTQ" = (/obj/machinery/power/apc{cell_type = 5000; dir = 8; environ = 1; equipment = 1; indestructible = 1; lighting = 1; locked = 0; name = "Worn-out APC"; pixel_x = -24; pixel_y = 0},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/greengrid/airless,/area/xenos_station/start) +"cTQ" = (/obj/machinery/power/apc{cell_type = 5000; dir = 8; environ = 1; equipment = 1; lighting = 1; locked = 0; name = "Worn-out APC"; pixel_x = -24; pixel_y = 0},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/greengrid/airless,/area/xenos_station/start) "cTR" = (/turf/simulated/floor/greengrid/airless,/area/xenos_station/start) "cTS" = (/obj/structure/flora/grass/green,/turf/simulated/floor/holofloor{tag = "icon-snow"; icon_state = "snow"},/area/holodeck/source_snowfield) "cTT" = (/obj/structure/stool,/turf/simulated/floor/holofloor{tag = "icon-carpet6-0 (EAST)"; icon_state = "carpet6-0"; dir = 4},/area/holodeck/source_meetinghall) @@ -7850,8 +7850,8 @@ "cUX" = (/obj/structure/rack,/obj/item/clothing/head/that{pixel_x = 4; pixel_y = 6},/obj/item/clothing/under/suit_jacket,/obj/item/clothing/suit/wcoat,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/ninja/holding) "cUY" = (/obj/item/weapon/beach_ball,/turf/unsimulated/beach/sand,/area/ninja/holding) "cUZ" = (/obj/structure/cable,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/smes/magical{name = "alien power storage unit"},/turf/simulated/floor/greengrid/airless,/area/xenos_station/start) -"cVa" = (/obj/machinery/camera{c_tag = "Xeno Shuttle South-West"; dir = 1; indestructible = 1; network = list("Xeno")},/obj/machinery/power/terminal{dir = 8},/turf/simulated/floor/greengrid/airless,/area/xenos_station/start) -"cVb" = (/obj/machinery/camera{c_tag = "Xeno Shuttle South-East"; dir = 1; indestructible = 1; network = list("Xeno")},/obj/effect/landmark{name = "Xenos-Spawn"; pixel_x = -1},/turf/simulated/floor/plating/airless,/area/xenos_station/start) +"cVa" = (/obj/machinery/camera{c_tag = "Xeno Shuttle South-East"; dir = 1; network = list("Xeno")},/obj/effect/landmark{name = "Xenos-Spawn"; pixel_x = -1},/turf/simulated/floor/plating/airless,/area/xenos_station/start) +"cVb" = (/obj/machinery/camera{c_tag = "CentCom Special Ops. Assault Armor North"; dir = 2; network = list("ERT","CentCom")},/obj/mecha/combat/marauder/seraph/loaded,/turf/unsimulated/floor{icon_state = "delivery"; dir = 6},/area/centcom/specops) "cVc" = (/obj/structure/flora/grass/brown,/turf/simulated/floor/holofloor{tag = "icon-snow"; icon_state = "snow"},/area/holodeck/source_snowfield) "cVd" = (/turf/simulated/floor/holofloor{dir = 2; icon_state = "green"},/area/holodeck/source_basketball) "cVe" = (/turf/simulated/floor/holofloor{icon_state = "sand"; name = "Soft sand"},/area/holodeck/source_beach) @@ -8111,7 +8111,7 @@ "cZY" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "cZZ" = (/obj/structure/rack,/obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "daa" = (/obj/structure/rack,/obj/item/weapon/tank/nitrogen,/obj/item/weapon/tank/nitrogen,/obj/item/weapon/tank/nitrogen,/obj/item/weapon/tank/nitrogen,/obj/item/weapon/tank/nitrogen,/obj/item/weapon/tank/nitrogen,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"dab" = (/obj/structure/rack,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/suit/space/vox/carapace,/obj/item/clothing/head/helmet/space/vox/carapace,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) +"dab" = (/obj/structure/rack,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/suit/space/vox/carapace,/obj/item/clothing/head/helmet/space/vox/carapace,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "dac" = (/obj/structure/rack,/obj/item/weapon/gun/dartgun/vox/raider,/obj/item/weapon/gun/dartgun/vox/medical,/obj/item/weapon/dart_cartridge,/obj/item/weapon/dart_cartridge,/obj/item/weapon/dart_cartridge,/obj/item/weapon/dart_cartridge,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "dad" = (/obj/machinery/sleeper/upgraded,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "dae" = (/obj/machinery/sleep_console,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) @@ -8124,7 +8124,7 @@ "dal" = (/turf/space/transit/north/shuttlespace_ns8,/area/vox_station/transit) "dam" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "diagonalWall3"},/area/shuttle/vox/station) "dan" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"dao" = (/obj/structure/rack,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/suit/space/vox/medic,/obj/item/clothing/head/helmet/space/vox/medic,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) +"dao" = (/obj/structure/rack,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/suit/space/vox/medic,/obj/item/clothing/head/helmet/space/vox/medic,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "dap" = (/obj/structure/rack,/obj/item/weapon/gun/launcher/pneumatic,/obj/item/weapon/harpoon,/obj/item/weapon/harpoon,/obj/item/weapon/harpoon,/obj/item/weapon/harpoon,/obj/item/weapon/tank/nitrogen,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "daq" = (/turf/space,/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/shuttle/vox/station) "dar" = (/turf/space/transit/north/shuttlespace_ns7,/area/vox_station/transit) @@ -8132,7 +8132,7 @@ "dat" = (/turf/space/transit/north/shuttlespace_ns12,/area/vox_station/transit) "dau" = (/turf/space/transit/north/shuttlespace_ns3,/area/vox_station/transit) "dav" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion_l"; icon_state = "propulsion_l"},/turf/space,/area/shuttle/vox/station) -"daw" = (/obj/structure/rack,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/suit/space/vox/pressure,/obj/item/clothing/head/helmet/space/vox/pressure,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) +"daw" = (/obj/structure/rack,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/suit/space/vox/pressure,/obj/item/clothing/head/helmet/space/vox/pressure,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "dax" = (/obj/structure/rack,/obj/item/weapon/gun/launcher/spikethrower,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "day" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; tiles = 0},/turf/space/transit/north/shuttlespace_ns15,/area) "daz" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 8; name = "thrower_escapeshuttletop(left)"; tiles = 0},/turf/space/transit/north/shuttlespace_ns4,/area) @@ -8146,7 +8146,7 @@ "daH" = (/turf/space/transit/north/shuttlespace_ns2,/area/vox_station/transit) "daI" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/turf/space/transit/north/shuttlespace_ns11,/area) "daJ" = (/turf/unsimulated/wall,/area/syndicate_mothership) -"daK" = (/obj/structure/rack,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/suit/space/vox/stealth,/obj/item/clothing/head/helmet/space/vox/stealth,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) +"daK" = (/obj/structure/rack,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/suit/space/vox/stealth,/obj/item/clothing/head/helmet/space/vox/stealth,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "daL" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; tiles = 0},/turf/space/transit/north/shuttlespace_ns8,/area) "daM" = (/turf/space/transit/north/shuttlespace_ns12,/area/shuttle/escape_pod1/transit) "daN" = (/turf/space/transit/north/shuttlespace_ns7,/area/shuttle/escape_pod1/transit) @@ -8199,7 +8199,7 @@ "dbI" = (/turf/space/transit/north/shuttlespace_ns8,/area/shuttle/escape_pod2/transit) "dbJ" = (/obj/structure/AIcore,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "dbK" = (/obj/item/weapon/spacecash/c200,/obj/item/weapon/spacecash/c50,/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"dbL" = (/obj/structure/jungle_plant,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) +"dbL" = (/obj/item/weapon/storage/box/zipties,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "dbM" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"},/area/syndicate_mothership) "dbN" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/syndicate_station/start) "dbO" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/syndicate_station/start) @@ -8245,7 +8245,7 @@ "dcC" = (/obj/machinery/door/airlock/centcom{name = "Study"; opacity = 1; req_access_txt = "150"},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "dcD" = (/turf/unsimulated/floor{icon_state = "grimy"},/area/syndicate_mothership) "dcE" = (/obj/structure/table,/obj/item/stack/cable_coil,/obj/item/weapon/crowbar/red,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) -"dcF" = (/obj/structure/table,/obj/item/weapon/storage/box/handcuffs,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) +"dcF" = (/obj/structure/table,/obj/item/weapon/storage/box/zipties,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) "dcG" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/unsimulated/floor{tag = "icon-gravsnow_surround (WEST)"; icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_surround"; dir = 8},/area/syndicate_mothership) "dcH" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/unsimulated/floor{tag = "icon-gravsnow_corner (SOUTHEAST)"; icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"; dir = 6},/area/syndicate_mothership) "dcI" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/drinks/cans/beer{pixel_x = -2; pixel_y = 5},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) @@ -8327,12 +8327,12 @@ "deg" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/structure/table,/obj/machinery/cell_charger,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) "deh" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/structure/table,/obj/machinery/recharger{pixel_y = 0},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) "dei" = (/obj/machinery/vending/wallmed1/syndicate{pixel_x = -30},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) -"dej" = (/obj/structure/table,/obj/item/weapon/cell/high{pixel_x = -3; pixel_y = 3},/obj/item/weapon/cell/high,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) +"dej" = (/obj/structure/table,/obj/item/weapon/stock_parts/cell/high{pixel_x = -3; pixel_y = 3},/obj/item/weapon/stock_parts/cell/high,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) "dek" = (/obj/structure/table,/obj/item/weapon/screwdriver{pixel_y = 9},/obj/item/device/assembly/voice{pixel_y = 3},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) "del" = (/obj/structure/table,/obj/item/weapon/wrench,/obj/item/device/assembly/infra,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) "dem" = (/obj/structure/table,/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/assembly/signaler,/obj/item/device/assembly/signaler,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) "den" = (/obj/structure/table,/obj/item/weapon/weldingtool/largetank,/obj/item/device/multitool,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) -"deo" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows2 (NORTH)"; icon_state = "fakewindows2"; dir = 1},/area/syndicate_mothership) +"deo" = (/turf/unsimulated/wall/fakeglass{dir = 8; icon_state = "fakewindows3"; tag = "icon-fakewindows (WEST)"},/area/syndicate_mothership) "dep" = (/obj/structure/stool{pixel_y = 8},/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/syndicate_mothership) "deq" = (/obj/machinery/door/window{dir = 4; name = "Infirmary"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) "der" = (/obj/machinery/door/window/westright{name = "Tool Storage"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start) @@ -8416,7 +8416,7 @@ "dfR" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/unsimulated/floor,/area/centcom/control) "dfS" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/turf/unsimulated/floor,/area/centcom/control) "dfT" = (/turf/unsimulated/wall,/area/centcom/specops) -"dfU" = (/turf/space,/area/centcom/specops) +"dfU" = (/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1441; name = "Spec Ops Intercom"; pixel_y = 28},/turf/unsimulated/floor{dir = 4; heat_capacity = 1; icon_state = "warning"},/area/centcom/specops) "dfV" = (/obj/structure/stool{pixel_y = 8},/turf/unsimulated/floor{tag = "icon-redyellowfull"; icon_state = "redyellowfull"},/area/centcom/control) "dfW" = (/obj/structure/closet/secure_closet/bar{req_access_txt = "25"},/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/control) "dfX" = (/obj/structure/reagent_dispensers/beerkeg,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/control) @@ -8425,11 +8425,11 @@ "dga" = (/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/control) "dgb" = (/obj/machinery/gibber,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/control) "dgc" = (/obj/machinery/mech_bay_recharge_port/upgraded,/turf/unsimulated/floor{icon_state = "bot"},/area/centcom/specops) -"dgd" = (/obj/machinery/camera{c_tag = "CentCom Special Ops. Assault Armor North"; dir = 2; network = list("ERT","CentCom")},/obj/mecha/combat/marauder/seraph,/turf/unsimulated/floor{icon_state = "delivery"; dir = 6},/area/centcom/specops) +"dgd" = (/obj/mecha/combat/marauder/loaded,/turf/unsimulated/floor{icon_state = "delivery"; dir = 6},/area/centcom/specops) "dge" = (/turf/unsimulated/floor{dir = 4; heat_capacity = 1; icon_state = "warning"},/area/centcom/specops) "dgf" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dgg" = (/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1441; listening = 0; name = "Spec Ops Intercom"; pixel_y = 28},/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dgh" = (/obj/machinery/recharge_station,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"dgg" = (/obj/machinery/door/poddoor{icon_state = "pdoor1"; id = "ASSAULT"; name = "Assault Armor Storage"; p_open = 0},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"dgh" = (/obj/structure/table/reinforced,/obj/item/weapon/twohanded/fireaxe,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "dgi" = (/obj/item/weapon/reagent_containers/food/condiment/saltshaker{pixel_x = -6},/obj/structure/table,/turf/unsimulated/floor{tag = "icon-redyellowfull"; icon_state = "redyellowfull"},/area/centcom/control) "dgj" = (/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/control) "dgk" = (/obj/structure/closet/secure_closet/freezer/meat,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/control) @@ -8444,7 +8444,7 @@ "dgt" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/drinks/shaker,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/control) "dgu" = (/obj/structure/table,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/control) "dgv" = (/obj/machinery/door/airlock/centcom{name = "Living Quarters"; opacity = 1; req_access_txt = "105"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/control) -"dgw" = (/obj/mecha/combat/marauder,/turf/unsimulated/floor{icon_state = "delivery"; dir = 6},/area/centcom/specops) +"dgw" = (/obj/mecha/combat/marauder/seraph/loaded,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "dgx" = (/obj/machinery/door/airlock/centcom{name = "Commander Quarters"; opacity = 1; req_access_txt = "109"},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/centcom/control) "dgy" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{name = "plating"},/area/centcom/control) "dgz" = (/obj/structure/stool{pixel_y = 8},/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/control) @@ -8466,23 +8466,23 @@ "dgP" = (/obj/structure/table,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/food/condiment/enzyme,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/control) "dgQ" = (/obj/structure/table,/obj/machinery/microwave/upgraded,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/control) "dgR" = (/obj/machinery/door/poddoor{icon_state = "pdoor1"; id = "ASSAULT1"; name = "Launch Bay #1"; p_open = 0},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) -"dgS" = (/obj/structure/rack,/obj/item/ammo_box/magazine/smgm9mm,/obj/item/ammo_box/magazine/smgm9mm,/obj/item/ammo_box/magazine/smgm9mm,/obj/item/ammo_box/magazine/smgm9mm,/obj/item/ammo_box/magazine/smgm9mm,/obj/item/ammo_box/magazine/smgm9mm,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"dgS" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/backpack/duffel/engineering{pixel_x = -3; pixel_y = 3},/obj/item/weapon/storage/backpack/duffel/engineering,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "dgT" = (/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) -"dgU" = (/obj/structure/rack,/obj/item/weapon/gun/projectile/automatic,/obj/item/weapon/gun/projectile/automatic,/obj/item/weapon/gun/projectile/automatic,/obj/item/weapon/gun/projectile/automatic,/obj/item/weapon/gun/projectile/automatic,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"dgU" = (/obj/structure/table/reinforced,/obj/item/weapon/grenade/chem_grenade/metalfoam,/obj/item/weapon/grenade/chem_grenade/metalfoam,/obj/item/weapon/grenade/chem_grenade/metalfoam,/obj/item/weapon/grenade/chem_grenade/metalfoam,/obj/item/weapon/grenade/chem_grenade/metalfoam,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "dgV" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/unsimulated/floor{name = "plating"},/area/centcom/control) "dgW" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/unsimulated/floor{name = "plating"},/area/centcom/control) "dgX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/unsimulated/floor{name = "plating"},/area/centcom/control) "dgY" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{name = "plating"},/area/centcom/control) "dgZ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{name = "plating"},/area/centcom/control) "dha" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{name = "plating"},/area/centcom/control) -"dhb" = (/obj/structure/rack,/obj/item/ammo_box/shotgun/buck,/obj/item/ammo_box/shotgun/buck,/obj/item/ammo_box/shotgun/buck,/obj/item/ammo_box/shotgun,/obj/item/ammo_box/shotgun,/obj/item/ammo_box/shotgun,/obj/item/ammo_box/shotgun/stun,/obj/item/ammo_box/shotgun/stun,/obj/item/ammo_box/shotgun/stun,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dhc" = (/obj/structure/rack,/obj/item/weapon/gun/projectile/shotgun/combat,/obj/item/weapon/gun/projectile/shotgun/combat,/obj/item/weapon/gun/projectile/shotgun/combat,/obj/item/weapon/gun/projectile/shotgun/combat,/obj/item/weapon/gun/projectile/shotgun/combat,/obj/item/weapon/gun/projectile/shotgun/combat,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"dhb" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/syringes,/obj/item/weapon/reagent_containers/glass/bottle/chloralhydrate{pixel_x = -3; pixel_y = 3},/obj/item/weapon/reagent_containers/glass/bottle/chloralhydrate,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"dhc" = (/obj/structure/table/reinforced,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag{pixel_x = -3; pixel_y = 3},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "dhd" = (/turf/unsimulated/floor{icon_state = "grass1"; name = "grass"},/area/centcom/control) "dhe" = (/obj/machinery/door/airlock/centcom{name = "Living Quarters"; opacity = 1; req_access_txt = "105"},/turf/unsimulated/floor{icon_state = "delivery"},/area/centcom/control) "dhf" = (/obj/machinery/door/poddoor{icon_state = "pdoor1"; id = "ASSAULT0"; name = "Launch Bay #0"; p_open = 0},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) "dhg" = (/obj/machinery/camera{c_tag = "CentCom Special Ops. Assault Armor South"; dir = 1; network = list("ERT","CentCom")},/turf/unsimulated/floor{icon_state = "loadingarea"; dir = 8},/area/centcom/specops) -"dhh" = (/obj/structure/rack,/obj/item/ammo_box/magazine/m762,/obj/item/ammo_box/magazine/m762,/obj/item/ammo_box/magazine/m762,/obj/item/ammo_box/magazine/m762,/obj/item/ammo_box/magazine/m762,/obj/item/ammo_box/magazine/m762,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dhi" = (/obj/structure/rack,/obj/item/weapon/gun/projectile/automatic/l6_saw{name = "light machine gun"},/obj/item/weapon/gun/projectile/automatic/l6_saw{name = "light machine gun"},/obj/item/weapon/gun/projectile/automatic/l6_saw{name = "light machine gun"},/obj/item/weapon/gun/projectile/automatic/l6_saw{name = "light machine gun"},/obj/item/weapon/gun/projectile/automatic/l6_saw{name = "light machine gun"},/obj/item/weapon/gun/projectile/automatic/l6_saw{name = "light machine gun"},/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"dhh" = (/obj/structure/table/reinforced,/obj/item/weapon/gun/syringe{pixel_x = -3; pixel_y = 3},/obj/item/weapon/gun/syringe,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"dhi" = (/obj/structure/table/reinforced,/obj/item/weapon/rcd_ammo/large,/obj/item/weapon/rcd_ammo/large,/obj/item/weapon/rcd_ammo/large,/obj/item/weapon/rcd_ammo/large,/obj/item/weapon/rcd_ammo/large,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "dhj" = (/turf/unsimulated/floor{icon_state = "green"; dir = 9},/area/centcom/control) "dhk" = (/turf/unsimulated/floor{icon_state = "green"; dir = 1},/area/centcom/control) "dhl" = (/turf/unsimulated/floor{icon_state = "green"; dir = 5},/area/centcom/control) @@ -8490,96 +8490,96 @@ "dhn" = (/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/control) "dho" = (/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "dhp" = (/turf/unsimulated/floor{icon_state = "green"; dir = 4},/area/centcom/control) -"dhq" = (/obj/structure/rack,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dhr" = (/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1441; listening = 0; name = "Spec Ops Intercom"; pixel_y = 28},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) -"dhs" = (/obj/structure/rack,/obj/item/weapon/gun/energy/ionrifle,/obj/item/weapon/gun/energy/ionrifle,/obj/item/weapon/gun/energy/ionrifle,/obj/item/weapon/gun/energy/ionrifle,/obj/item/weapon/gun/energy/ionrifle,/obj/item/weapon/gun/energy/ionrifle,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dht" = (/obj/structure/rack,/obj/item/weapon/grenade/chem_grenade/incendiary{name = "Incendiary Grenade"},/obj/item/weapon/grenade/chem_grenade/incendiary{name = "Incendiary Grenade"},/obj/item/weapon/grenade/chem_grenade/incendiary{name = "Incendiary Grenade"},/obj/item/weapon/grenade/chem_grenade/incendiary{name = "Incendiary Grenade"},/obj/item/weapon/grenade/chem_grenade/incendiary{name = "Incendiary Grenade"},/obj/item/weapon/grenade/chem_grenade/incendiary{name = "Incendiary Grenade"},/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dhu" = (/obj/structure/rack,/obj/item/weapon/gun/energy/lasercannon,/obj/item/weapon/gun/energy/lasercannon,/obj/item/weapon/gun/energy/lasercannon,/obj/item/weapon/gun/energy/lasercannon,/obj/item/weapon/gun/energy/lasercannon,/obj/item/weapon/gun/energy/lasercannon,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"dhq" = (/obj/structure/table/reinforced,/obj/item/weapon/tank/jetpack/oxygen/harness,/obj/item/weapon/tank/jetpack/oxygen/harness{pixel_x = -3; pixel_y = 3},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"dhr" = (/obj/structure/table/reinforced,/obj/item/weapon/reagent_containers/hypospray/combat/nanites{pixel_x = -3; pixel_y = 3},/obj/item/weapon/reagent_containers/hypospray/combat/nanites,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"dhs" = (/obj/structure/table/reinforced,/obj/item/clothing/glasses/hud/health/night{pixel_x = -3; pixel_y = 3},/obj/item/clothing/glasses/hud/health/night,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"dht" = (/obj/machinery/door/poddoor{desc = "Good luck hacking this one open."; icon_state = "pdoor1"; id = "WEAPONS"; name = "Special Weaponry"; p_open = 0},/obj/machinery/door/airlock/centcom{name = "Armory - Engineering"; opacity = 1; req_access_txt = "106"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"dhu" = (/obj/machinery/door/poddoor{desc = "Good luck hacking this one open."; icon_state = "pdoor1"; id = "WEAPONS"; name = "Special Weaponry"; p_open = 0},/obj/machinery/door/airlock/centcom{name = "Armory - Medical"; opacity = 1; req_access_txt = "104"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "dhv" = (/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/living) "dhw" = (/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/living) "dhx" = (/turf/unsimulated/floor{icon_state = "green"; dir = 4},/area/centcom/living) -"dhy" = (/obj/structure/rack,/obj/item/weapon/grenade/empgrenade,/obj/item/weapon/grenade/empgrenade,/obj/item/weapon/grenade/empgrenade,/obj/item/weapon/grenade/empgrenade,/obj/item/weapon/grenade/empgrenade,/obj/item/weapon/grenade/empgrenade,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dhz" = (/obj/structure/rack,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/gun/energy/gun/nuclear,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"dhy" = (/obj/structure/table/reinforced,/obj/item/clothing/glasses/thermal,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"dhz" = (/obj/structure/table/reinforced,/obj/item/weapon/hand_tele,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "dhA" = (/turf/unsimulated/floor{icon_state = "greencorner"; dir = 1},/area/centcom/control) "dhB" = (/turf/unsimulated/floor{icon_state = "greencorner"; dir = 4},/area/centcom/control) -"dhC" = (/obj/structure/rack,/obj/item/weapon/gun/grenadelauncher,/obj/item/weapon/gun/grenadelauncher,/obj/item/weapon/gun/grenadelauncher,/obj/item/weapon/gun/grenadelauncher,/obj/item/weapon/gun/grenadelauncher,/obj/item/weapon/gun/grenadelauncher,/obj/item/weapon/grenade/chem_grenade/teargas{name = "Teargas"},/obj/item/weapon/grenade/chem_grenade/teargas{name = "Teargas"},/obj/item/weapon/grenade/chem_grenade/teargas{name = "Teargas"},/obj/item/weapon/grenade/chem_grenade/teargas{name = "Teargas"},/obj/item/weapon/grenade/chem_grenade/teargas{name = "Teargas"},/obj/item/weapon/grenade/chem_grenade/teargas{name = "Teargas"},/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dhD" = (/obj/structure/rack,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dhE" = (/obj/structure/rack,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1441; listening = 0; name = "Spec Ops Intercom"; pixel_y = 28},/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dhF" = (/obj/structure/rack,/obj/item/weapon/gun/energy/stunrevolver,/obj/item/weapon/gun/energy/stunrevolver,/obj/item/weapon/gun/energy/stunrevolver,/obj/item/weapon/gun/energy/stunrevolver,/obj/item/weapon/gun/energy/stunrevolver,/obj/item/weapon/gun/energy/stunrevolver,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dhG" = (/obj/structure/rack,/obj/item/weapon/storage/box/flashbangs,/obj/item/weapon/storage/box/flashbangs,/obj/item/weapon/storage/box/flashbangs,/obj/item/weapon/storage/box/flashbangs,/obj/item/weapon/storage/box/flashbangs,/obj/item/weapon/storage/box/flashbangs,/obj/item/weapon/storage/box/teargas,/obj/item/weapon/storage/box/teargas,/obj/item/weapon/storage/box/teargas,/obj/item/weapon/storage/box/teargas,/obj/item/weapon/storage/box/teargas,/obj/item/weapon/storage/box/teargas,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dhH" = (/obj/structure/table/reinforced,/obj/item/weapon/defibrillator/loaded,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dhI" = (/obj/structure/table/reinforced,/obj/item/weapon/reagent_containers/hypospray/CMO,/obj/item/weapon/reagent_containers/hypospray/CMO,/obj/item/weapon/reagent_containers/hypospray/CMO,/obj/item/weapon/reagent_containers/hypospray/CMO,/obj/item/weapon/reagent_containers/hypospray/CMO,/obj/item/weapon/reagent_containers/hypospray/CMO,/obj/item/weapon/storage/box/gloves,/obj/item/weapon/storage/box/gloves,/obj/item/weapon/storage/box/gloves,/obj/item/weapon/storage/box/gloves,/obj/item/weapon/storage/box/gloves,/obj/item/weapon/storage/box/gloves,/obj/item/weapon/storage/box/masks,/obj/item/weapon/storage/box/masks,/obj/item/weapon/storage/box/masks,/obj/item/weapon/storage/box/masks,/obj/item/weapon/storage/box/masks,/obj/item/weapon/storage/box/masks,/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1441; listening = 0; name = "Spec Ops Intercom"; pixel_y = 28},/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dhJ" = (/obj/machinery/vending/medical,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dhK" = (/obj/structure/table/reinforced,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/storage/box/autoinjectors,/obj/item/weapon/storage/box/autoinjectors,/obj/item/weapon/storage/box/autoinjectors,/obj/item/weapon/storage/box/autoinjectors,/obj/item/weapon/storage/box/autoinjectors,/obj/item/weapon/storage/box/autoinjectors,/obj/item/weapon/storage/box/syringes,/obj/item/weapon/storage/box/syringes,/obj/item/weapon/storage/box/syringes,/obj/item/weapon/storage/box/syringes,/obj/item/weapon/storage/box/syringes,/obj/item/weapon/storage/box/syringes,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dhL" = (/obj/machinery/door/poddoor{desc = "Good luck hacking this one open."; icon_state = "pdoor1"; id = "WEAPONS"; name = "Special Weaponry"; p_open = 0},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) +"dhC" = (/obj/structure/piano,/turf/unsimulated/floor{tag = "icon-redyellowfull"; icon_state = "redyellowfull"},/area/centcom/control) +"dhD" = (/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1441; name = "Spec Ops Intercom"; pixel_y = 28},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"dhE" = (/obj/structure/table/reinforced,/obj/item/weapon/paper,/obj/item/weapon/pen,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"dhF" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/lockbox/loyalty,/obj/item/weapon/storage/lockbox/loyalty{pixel_x = -3; pixel_y = 3},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"dhG" = (/obj/machinery/door/poddoor{desc = "Good luck hacking this one open."; icon_state = "pdoor1"; id = "WEAPONS"; name = "Special Weaponry"; p_open = 0},/obj/machinery/door/airlock/centcom{name = "Armory - Commander"; opacity = 1; req_access_txt = "107"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"dhH" = (/obj/structure/table/reinforced,/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1443; listening = 0; name = "Response Team Intercom"; pixel_y = 0},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"dhI" = (/obj/machinery/recharger/wallcharger{pixel_x = 30},/obj/structure/rack,/obj/item/weapon/gun/energy/pulse_rifle/pistol/m1911,/obj/item/weapon/gun/energy/pulse_rifle/pistol/m1911{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) +"dhJ" = (/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"dhK" = (/obj/structure/table/reinforced,/obj/item/weapon/gun/energy/pulse_rifle/pistol,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"dhL" = (/obj/structure/table/reinforced,/obj/item/weapon/gun/energy/ionrifle,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "dhM" = (/turf/unsimulated/floor{icon_state = "greencorner"},/area/centcom/control) "dhN" = (/turf/unsimulated/floor{icon_state = "green"},/area/centcom/control) "dhO" = (/turf/unsimulated/floor{icon_state = "greencorner"; dir = 8},/area/centcom/control) -"dhP" = (/obj/structure/rack,/obj/item/clothing/head/helmet/space/rig/ert/security,/obj/item/clothing/suit/space/rig/ert/security,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/head/helmet/space/rig/ert/security,/obj/item/clothing/suit/space/rig/ert/security,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/head/helmet/space/rig/ert/security,/obj/item/clothing/suit/space/rig/ert/security,/obj/item/clothing/tie/storage/black_vest,/obj/item/weapon/storage/belt/security,/obj/item/weapon/storage/belt/security,/obj/item/weapon/storage/belt/security,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"dhP" = (/obj/structure/sign/double/map/left,/turf/unsimulated/floor{icon_state = "light_on"},/area/centcom/specops) "dhQ" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) -"dhR" = (/obj/structure/table/reinforced,/obj/item/clothing/glasses/sunglasses/sechud,/obj/item/clothing/glasses/sunglasses/sechud,/obj/item/clothing/glasses/sunglasses/sechud,/obj/item/clothing/glasses/sunglasses/sechud,/obj/item/clothing/glasses/sunglasses/sechud,/obj/item/clothing/glasses/sunglasses/sechud,/obj/item/clothing/glasses/hud/security/night,/obj/item/clothing/glasses/hud/security/night,/obj/item/clothing/glasses/hud/security/night,/obj/item/clothing/glasses/hud/security/night,/obj/item/clothing/glasses/hud/security/night,/obj/item/clothing/glasses/hud/security/night,/obj/item/clothing/glasses/night,/obj/item/clothing/glasses/night,/obj/item/clothing/glasses/night,/obj/item/clothing/glasses/night,/obj/item/clothing/glasses/night,/obj/item/clothing/glasses/night,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dhS" = (/obj/structure/rack,/obj/item/clothing/head/helmet/space/rig/ert/medical,/obj/item/clothing/suit/space/rig/ert/medical,/obj/item/clothing/head/helmet/space/rig/ert/medical,/obj/item/clothing/suit/space/rig/ert/medical,/obj/item/clothing/head/helmet/space/rig/ert/medical,/obj/item/clothing/suit/space/rig/ert/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dhT" = (/obj/structure/table/reinforced,/obj/item/clothing/glasses/hud/health_advanced,/obj/item/clothing/glasses/hud/health_advanced,/obj/item/clothing/glasses/hud/health_advanced,/obj/item/clothing/glasses/hud/health_advanced,/obj/item/clothing/glasses/hud/health_advanced,/obj/item/clothing/glasses/hud/health_advanced,/obj/item/clothing/glasses/hud/health/night,/obj/item/clothing/glasses/hud/health/night,/obj/item/clothing/glasses/hud/health/night,/obj/item/clothing/glasses/hud/health/night,/obj/item/clothing/glasses/hud/health/night,/obj/item/clothing/glasses/hud/health/night,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dhU" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"dhR" = (/obj/structure/table/reinforced,/obj/item/ashtray/glass{icon_state = "ashtray_half_gl"},/obj/item/weapon/cigbutt/cigarbutt{pixel_x = 3; pixel_y = 3},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"dhS" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics) +"dhT" = (/obj/structure/sign/double/map/right,/turf/unsimulated/floor{icon_state = "light_on"},/area/centcom/specops) +"dhU" = (/obj/machinery/door/poddoor{desc = "Good luck hacking this one open."; icon_state = "pdoor1"; id = "WEAPONS"; name = "Special Weaponry"; p_open = 0},/obj/machinery/door/airlock/centcom{name = "Armory - Security"; opacity = 1; req_access_txt = "102"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "dhV" = (/obj/effect/landmark{name = "Response Team"},/obj/effect/landmark{name = "Commando"},/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "dhW" = (/obj/structure/table,/obj/machinery/recharger{pixel_y = 4},/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1441; listening = 0; name = "Spec Ops Intercom"; pixel_y = 28},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) -"dhX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) +"dhX" = (/turf/unsimulated/wall/fakeglass{dir = 8; icon_state = "fakewindows3"; tag = "icon-fakewindows (WEST)"},/area/centcom/specops) "dhY" = (/turf/unsimulated/floor{icon_state = "asteroid6"; name = "sand"},/area/centcom/specops) "dhZ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{name = "plating"},/area/centcom/control) "dia" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{name = "plating"},/area/centcom/control) -"dib" = (/obj/structure/table/reinforced,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/melee/baton/loaded,/obj/item/device/flash,/obj/item/device/flash,/obj/item/device/flash,/obj/item/device/flash,/obj/item/device/flash,/obj/item/device/flash,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dic" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/firstaid/toxin,/obj/item/weapon/storage/firstaid/toxin,/obj/item/weapon/storage/firstaid/toxin,/obj/item/weapon/storage/firstaid/fire,/obj/item/weapon/storage/firstaid/fire,/obj/item/weapon/storage/firstaid/fire,/obj/item/weapon/storage/firstaid/o2,/obj/item/weapon/storage/firstaid/o2,/obj/item/weapon/storage/firstaid/o2,/obj/item/weapon/storage/firstaid/adv,/obj/item/weapon/storage/firstaid/adv,/obj/item/weapon/storage/firstaid/adv,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"did" = (/obj/machinery/portable_atmospherics/canister/air,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"die" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 9},/area/centcom/specops) +"dib" = (/obj/structure/table/reinforced,/obj/item/weapon/plastique{pixel_x = 3},/obj/item/weapon/plastique{pixel_x = 3},/obj/item/weapon/plastique{pixel_x = -3},/obj/item/weapon/plastique{pixel_x = 3},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"dic" = (/obj/structure/table/reinforced,/obj/item/clothing/glasses/hud/security/night{pixel_x = -3; pixel_y = 3},/obj/item/clothing/glasses/hud/security/night,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"did" = (/obj/structure/table/reinforced,/obj/item/weapon/gun/energy/pulse_rifle/carbine,/obj/item/weapon/gun/energy/pulse_rifle/carbine{pixel_x = -3; pixel_y = 3},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"die" = (/obj/structure/table/reinforced,/obj/item/weapon/shield/energy,/obj/item/weapon/shield/energy{pixel_x = -3; pixel_y = 3},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "dif" = (/obj/machinery/door/airlock/centcom{name = "Special Operations"; opacity = 1; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) "dig" = (/obj/structure/stool/bed/chair{dir = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "dih" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{name = "plating"},/area/centcom/control) "dii" = (/obj/machinery/computer/message_monitor,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) -"dij" = (/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1441; listening = 0; name = "Spec Ops Intercom"; pixel_y = 28},/obj/structure/stool/bed/chair/office/dark{dir = 8},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) -"dik" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/telecomms/relay/preset/centcom,/turf/unsimulated/floor{icon_state = "gcircuit"},/area/centcom/control) +"dij" = (/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "gcircuit"},/area/centcom/control) +"dik" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1441; listening = 0; name = "Spec Ops Intercom"; pixel_y = 28},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "dil" = (/mob/living/silicon/decoy{name = "A.L.I.C.E."},/turf/unsimulated/floor{icon_state = "gcircuit"},/area/centcom/control) "dim" = (/obj/structure/window/reinforced{dir = 4},/obj/machinery/blackbox_recorder,/turf/unsimulated/floor{icon_state = "gcircuit"},/area/centcom/control) "din" = (/obj/machinery/computer/card/centcom,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "dio" = (/obj/machinery/computer/card,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) -"dip" = (/obj/structure/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/gloves/swat,/obj/item/clothing/gloves/swat,/obj/item/clothing/gloves/swat,/obj/item/clothing/gloves/swat,/obj/item/clothing/gloves/swat,/obj/item/clothing/gloves/swat,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"diq" = (/obj/structure/table/reinforced,/obj/item/weapon/kitchenknife/combat,/obj/item/weapon/kitchenknife/combat,/obj/item/weapon/kitchenknife/combat,/obj/item/weapon/kitchenknife/combat,/obj/item/weapon/kitchenknife/combat,/obj/item/weapon/kitchenknife/combat,/obj/item/weapon/storage/box/handcuffs,/obj/item/weapon/storage/box/handcuffs,/obj/item/weapon/storage/box/handcuffs,/obj/item/weapon/storage/box/handcuffs,/obj/item/weapon/storage/box/handcuffs,/obj/item/weapon/storage/box/handcuffs,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dir" = (/obj/structure/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/gloves/color/latex,/obj/item/clothing/gloves/color/latex,/obj/item/clothing/gloves/color/latex,/obj/item/clothing/gloves/color/latex,/obj/item/clothing/gloves/color/latex,/obj/item/clothing/gloves/color/latex,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dis" = (/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/obj/structure/table/reinforced,/obj/item/weapon/storage/box/bodybags,/obj/item/weapon/storage/box/bodybags,/obj/item/weapon/storage/box/bodybags,/obj/item/weapon/storage/box/bodybags,/obj/item/weapon/storage/box/bodybags,/obj/item/weapon/storage/box/bodybags,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dit" = (/obj/structure/reagent_dispensers/watertank,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"dip" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/flashbangs{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/box/flashbangs,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"diq" = (/turf/unsimulated/floor{name = "plating"},/area) +"dir" = (/turf/unsimulated/floor{name = "plating"},/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/specops/centcom) +"dis" = (/turf/unsimulated/floor{name = "plating"},/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/shuttle/specops/centcom) +"dit" = (/obj/machinery/porta_turret/stationary,/turf/simulated/floor/plating/airless,/area/turret_protected/tcomsat) "diu" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows (WEST)"; icon_state = "fakewindows"; dir = 8},/area/centcom/specops) "div" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows2 (WEST)"; icon_state = "fakewindows2"; dir = 8},/area/centcom/specops) "diw" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows (EAST)"; icon_state = "fakewindows"; dir = 4},/area/centcom/specops) "dix" = (/obj/structure/window/reinforced,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "diy" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{name = "plating"},/area/centcom/control) -"diz" = (/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) -"diA" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) +"diz" = (/obj/structure/table/reinforced,/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1443; listening = 0; name = "Response Team Intercom"; pixel_y = 0},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) +"diA" = (/obj/machinery/telecomms/server/presets/centcomm,/turf/unsimulated/floor{icon_state = "green"; dir = 9},/area/centcom/control) "diB" = (/turf/unsimulated/floor{tag = "icon-warning"; icon_state = "warning"},/area/centcom/control) "diC" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) -"diD" = (/obj/machinery/door/airlock/centcom{name = "Security Special Operations"; opacity = 1; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) -"diE" = (/obj/machinery/door/airlock/centcom{name = "Medical Special Operations"; opacity = 1; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"diD" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'LETHAL TURRETS'. Enter at your own risk!"; name = "LETHAL TURRETS"; pixel_x = -32; pixel_y = 0},/obj/machinery/porta_turret{dir = 4},/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/turret_protected/tcomfoyer) +"diE" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'LETHAL TURRETS'. Enter at your own risk!"; name = "LETHAL TURRETS"; pixel_x = 32; pixel_y = 0},/obj/machinery/porta_turret{dir = 8},/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/turret_protected/tcomfoyer) "diF" = (/obj/machinery/door/poddoor{icon_state = "pdoor1"; id = "CREED"; name = "Ready Room"; p_open = 0},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) "diG" = (/turf/unsimulated/floor{icon_state = "bot"},/area/centcom/specops) "diH" = (/obj/machinery/door/airlock/centcom{name = "Special Operations"; opacity = 1; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "delivery"},/area/centcom/specops) "diI" = (/obj/machinery/door/airlock/centcom{name = "Special Operations"; opacity = 1; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "delivery"},/area/centcom/control) "diJ" = (/obj/machinery/door/airlock/centcom{name = "Bridge"; opacity = 1; req_access_txt = "109"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) -"diK" = (/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1443; listening = 0; name = "Response Team Intercom"; pixel_y = 28},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) +"diK" = (/obj/machinery/telecomms/processor/preset_cent,/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/control) "diL" = (/obj/machinery/door/airlock/centcom{name = "Administration Wing"; opacity = 1; req_access_txt = "999"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) -"diM" = (/obj/machinery/vending/tool,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"diN" = (/obj/machinery/vending/engivend,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"diO" = (/obj/machinery/vending/engineering,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"diP" = (/obj/structure/reagent_dispensers/fueltank,/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1441; listening = 0; name = "Spec Ops Intercom"; pixel_y = 28},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) -"diQ" = (/obj/structure/sign/securearea{name = "\improper ARMORY"; pixel_y = 32},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) -"diR" = (/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1441; listening = 0; name = "Spec Ops Intercom"; pixel_y = 28},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) -"diS" = (/obj/structure/sign/redcross{pixel_y = 32},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) +"diM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) +"diN" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) +"diO" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) +"diP" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) +"diQ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) +"diR" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) +"diS" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) "diT" = (/obj/structure/mopbucket,/obj/structure/mopbucket,/obj/structure/mopbucket,/obj/structure/mopbucket,/obj/structure/mopbucket,/obj/structure/mopbucket,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"diU" = (/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows (EAST)"; icon_state = "fakewindows"; dir = 4},/area/centcom/specops) +"diU" = (/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/turf/unsimulated/wall/fakeglass{dir = 8; icon_state = "fakewindows3"; tag = "icon-fakewindows (WEST)"},/area/centcom/specops) "diV" = (/obj/machinery/door/airlock/centcom{name = "Special Operations Command"; opacity = 1; req_access_txt = "108"},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) -"diW" = (/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows (WEST)"; icon_state = "fakewindows"; dir = 8},/area/centcom/specops) +"diW" = (/obj/structure/shuttle/engine/heater{tag = "icon-heater (WEST)"; icon_state = "heater"; dir = 8},/obj/structure/window/plasmareinforced{color = "#FF0000"; dir = 4},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/administration/centcom) "diX" = (/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "diY" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{name = "plating"},/area/centcom/control) -"diZ" = (/obj/structure/rack,/obj/item/clothing/head/helmet/space/rig/ert/engineer,/obj/item/clothing/suit/space/rig/ert/engineer,/obj/item/clothing/tie/storage/brown_vest,/obj/item/clothing/head/helmet/space/rig/ert/engineer,/obj/item/clothing/suit/space/rig/ert/engineer,/obj/item/clothing/tie/storage/brown_vest,/obj/item/clothing/head/helmet/space/rig/ert/engineer,/obj/item/clothing/suit/space/rig/ert/engineer,/obj/item/clothing/tie/storage/brown_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"dja" = (/obj/machinery/door/airlock/centcom{name = "Engineering Special Operations"; opacity = 1; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) -"djb" = (/obj/structure/stool/bed/chair,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"diZ" = (/turf/simulated/wall,/area/aisat/entrance) +"dja" = (/turf/simulated/wall/r_wall,/area/aisat/entrance) +"djb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/aisat/entrance) "djc" = (/obj/structure/table/reinforced,/obj/item/device/lightreplacer,/obj/item/device/lightreplacer,/obj/item/device/lightreplacer,/obj/item/device/lightreplacer,/obj/item/device/lightreplacer,/obj/item/device/lightreplacer,/obj/item/weapon/grenade/chem_grenade/cleaner{name = "cleaner grenade"},/obj/item/weapon/grenade/chem_grenade/cleaner{name = "cleaner grenade"},/obj/item/weapon/grenade/chem_grenade/cleaner{name = "cleaner grenade"},/obj/item/weapon/grenade/chem_grenade/cleaner{name = "cleaner grenade"},/obj/item/weapon/grenade/chem_grenade/cleaner{name = "cleaner grenade"},/obj/item/weapon/grenade/chem_grenade/cleaner{name = "cleaner grenade"},/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "djd" = (/obj/structure/table/woodentable{dir = 9},/obj/item/weapon/paper_bin,/obj/item/weapon/pen/fluff/fountainpen,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/specops) "dje" = (/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/specops) @@ -8589,11 +8589,11 @@ "dji" = (/obj/structure/stool/bed/chair/office/dark,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "djj" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "djk" = (/obj/machinery/computer/med_data,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) -"djl" = (/obj/structure/stool/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) -"djm" = (/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) -"djn" = (/obj/structure/table/reinforced,/obj/machinery/recharger{pixel_y = 4},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"djl" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/aisat/entrance) +"djm" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/aisat/entrance) +"djn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/crew_quarters/captain) "djo" = (/obj/structure/table/reinforced,/obj/effect/landmark{name = "Commando_Manual"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) -"djp" = (/obj/structure/stool/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"djp" = (/turf/simulated/wall,/area/turret_protected/aisat_interior) "djq" = (/obj/structure/table/reinforced,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/reagent_containers/spray/plantbgone,/obj/item/weapon/reagent_containers/spray/plantbgone,/obj/item/weapon/reagent_containers/spray/plantbgone,/obj/item/weapon/reagent_containers/spray/plantbgone,/obj/item/weapon/reagent_containers/spray/plantbgone,/obj/item/weapon/reagent_containers/spray/plantbgone,/obj/item/weapon/storage/box/lights/mixed,/obj/item/weapon/storage/box/lights/mixed,/obj/item/weapon/storage/box/lights/mixed,/obj/item/weapon/storage/box/lights/mixed,/obj/item/weapon/storage/box/lights/mixed,/obj/item/weapon/storage/box/lights/mixed,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "djr" = (/obj/item/device/radio/intercom{broadcasting = 1; dir = 8; listening = 0; name = "Station Intercom (General)"; pixel_x = -28},/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/specops) "djs" = (/turf/unsimulated/floor{dir = 9; icon_state = "carpetside"},/area/centcom/specops) @@ -8604,27 +8604,27 @@ "djx" = (/obj/machinery/computer/communications,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "djy" = (/obj/machinery/computer/robotics,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "djz" = (/obj/machinery/computer/crew,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) -"djA" = (/obj/structure/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"djB" = (/obj/structure/table/reinforced,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/meson,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/utility/full,/obj/item/device/multitool,/obj/item/device/multitool,/obj/item/device/multitool,/obj/item/device/multitool,/obj/item/device/multitool,/obj/item/device/multitool,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"djC" = (/obj/structure/table/reinforced,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd,/obj/item/weapon/rcd,/obj/item/weapon/rcd,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"djD" = (/obj/structure/table/reinforced,/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/stack/sheet/plasteel{amount = 50},/obj/item/stack/sheet/plasteel{amount = 50},/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"djE" = (/obj/machinery/door/airlock/centcom{name = "ERT Commander"; opacity = 1; req_access_txt = "107"},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) +"djA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/turret_protected/aisat_interior) +"djB" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/turret_protected/aisat_interior) +"djC" = (/turf/simulated/wall,/area/aisat) +"djD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/turret_protected/ai) +"djE" = (/turf/simulated/wall/r_wall,/area/turret_protected/ai) "djF" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "djG" = (/obj/structure/table/reinforced,/obj/item/weapon/mop/advanced,/obj/item/weapon/mop/advanced,/obj/item/weapon/mop/advanced,/obj/item/weapon/mop/advanced,/obj/item/weapon/mop/advanced,/obj/item/weapon/mop/advanced,/obj/item/weapon/reagent_containers/glass/rag,/obj/item/weapon/reagent_containers/glass/rag,/obj/item/weapon/reagent_containers/glass/rag,/obj/item/weapon/reagent_containers/glass/rag,/obj/item/weapon/reagent_containers/glass/rag,/obj/item/weapon/reagent_containers/glass/rag,/obj/item/weapon/reagent_containers/spray/cleaner,/obj/item/weapon/reagent_containers/spray/cleaner,/obj/item/weapon/reagent_containers/spray/cleaner,/obj/item/weapon/reagent_containers/spray/cleaner,/obj/item/weapon/reagent_containers/spray/cleaner,/obj/item/weapon/reagent_containers/spray/cleaner,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "djH" = (/obj/structure/table/woodentable{dir = 9},/obj/item/ashtray/glass{icon_state = "ashtray_half_gl"},/turf/unsimulated/floor{dir = 8; icon_state = "carpetside"},/area/centcom/specops) "djI" = (/obj/machinery/computer/security/telescreen{name = "Special Ops. Monitor"; desc = "Used for watching the Special Ops."; network = list("ERT")},/obj/structure/table/woodentable{dir = 5},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/specops) "djJ" = (/obj/structure/table/woodentable{dir = 5},/turf/unsimulated/floor{dir = 4; icon_state = "carpetside"},/area/centcom/specops) "djK" = (/obj/machinery/computer/shuttle_control/specops,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/specops) -"djL" = (/obj/structure/rack,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/security,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) -"djM" = (/obj/structure/table/reinforced,/obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/device/multitool,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) +"djL" = (/obj/structure/sign/securearea,/turf/simulated/wall/r_wall,/area/turret_protected/ai) +"djM" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/turret_protected/ai) "djN" = (/obj/structure/rack,/obj/item/clothing/mask/gas/swat,/obj/item/clothing/mask/gas/swat,/obj/item/clothing/mask/gas/swat,/obj/item/clothing/mask/gas/swat,/obj/item/clothing/mask/gas/swat,/obj/item/clothing/mask/gas/swat,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "djO" = (/obj/structure/rack,/obj/item/clothing/suit/bio_suit/janitor,/obj/item/clothing/suit/bio_suit/janitor,/obj/item/clothing/suit/bio_suit/janitor,/obj/item/clothing/suit/bio_suit/janitor,/obj/item/clothing/suit/bio_suit/janitor,/obj/item/clothing/suit/bio_suit/janitor,/obj/item/clothing/head/bio_hood/janitor,/obj/item/clothing/head/bio_hood/janitor,/obj/item/clothing/head/bio_hood/janitor,/obj/item/clothing/head/bio_hood/janitor,/obj/item/clothing/head/bio_hood/janitor,/obj/item/clothing/head/bio_hood/janitor,/obj/item/clothing/gloves/purple,/obj/item/clothing/gloves/purple,/obj/item/clothing/gloves/purple,/obj/item/clothing/gloves/purple,/obj/item/clothing/gloves/purple,/obj/item/clothing/gloves/purple,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "djP" = (/obj/structure/table/woodentable{dir = 10},/obj/machinery/door_control{desc = "A remote control switch to block view of the singularity."; icon_state = "doorctrl0"; id = "CREED"; name = "Spec Ops Ready Room"; pixel_y = 16; req_access_txt = "108"},/obj/machinery/door_control{desc = "A remote control switch to block view of the singularity."; icon_state = "doorctrl0"; id = "ASSAULT"; name = "Mech Storage"; pixel_y = -4; req_access_txt = "108"},/obj/machinery/door_control{desc = "A remote control switch to block view of the singularity."; icon_state = "doorctrl0"; id = "WEAPONS"; name = "Armory Door"; pixel_y = 6; req_access_txt = "108"},/turf/unsimulated/floor{dir = 8; icon_state = "carpetside"},/area/centcom/specops) "djQ" = (/obj/structure/stool/bed/chair/comfy/black{tag = "icon-comfychair_black (NORTH)"; icon_state = "comfychair_black"; dir = 1},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/specops) "djR" = (/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1441; name = "Spec Ops Intercom"; pixel_y = 28},/obj/machinery/computer/shuttle_control{name = "gamma operations control console"; req_one_access_txt = "32"; shuttle_tag = "Gamma"},/turf/unsimulated/floor{dir = 4; icon_state = "carpetside"},/area/centcom/specops) "djS" = (/obj/structure/stool/bed/chair{dir = 1},/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/specops) -"djT" = (/obj/structure/rack,/obj/item/clothing/head/helmet/space/rig/ert/commander,/obj/item/clothing/suit/space/rig/ert/commander,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/holster/armpit,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) -"djU" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/flashbangs,/obj/item/weapon/storage/box/handcuffs,/obj/item/weapon/storage/box/teargas,/obj/item/weapon/melee/baton/loaded,/obj/item/device/flash,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) +"djT" = (/turf/simulated/wall/r_wall,/area/aisat) +"djU" = (/turf/simulated/wall/r_wall,/area/aisat/maintenance) "djV" = (/obj/structure/rack,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "djW" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "specops_centcom_dock"; pixel_y = -25; req_access_txt = "101"; tag_door = "specops_centcom_dock_inner"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "djX" = (/obj/structure/rack,/obj/item/clothing/shoes/galoshes,/obj/item/clothing/shoes/galoshes,/obj/item/clothing/shoes/galoshes,/obj/item/clothing/shoes/galoshes,/obj/item/clothing/shoes/galoshes,/obj/item/clothing/shoes/galoshes,/obj/item/weapon/storage/belt/janitor,/obj/item/weapon/storage/belt/janitor,/obj/item/weapon/storage/belt/janitor,/obj/item/weapon/storage/belt/janitor,/obj/item/weapon/storage/belt/janitor,/obj/item/weapon/storage/belt/janitor,/obj/item/clothing/glasses/science,/obj/item/clothing/glasses/science,/obj/item/clothing/glasses/science,/obj/item/clothing/glasses/science,/obj/item/clothing/glasses/science,/obj/item/clothing/glasses/science,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) @@ -8634,8 +8634,8 @@ "dkb" = (/turf/simulated/shuttle/wall{icon_state = "swall_s6"; dir = 2},/area/shuttle/escape/centcom) "dkc" = (/obj/structure/grille,/obj/structure/window/full/shuttle,/turf/simulated/floor/plating,/area/shuttle/escape/centcom) "dkd" = (/turf/simulated/shuttle/wall{icon_state = "swall_s10"; dir = 2},/area/shuttle/escape/centcom) -"dke" = (/obj/structure/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/night,/obj/item/clothing/glasses/sunglasses/sechud,/obj/item/clothing/glasses/hud/health_advanced,/obj/item/clothing/glasses/hud/security/night,/obj/item/clothing/glasses/hud/health/night,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/swat,/obj/item/clothing/gloves/color/latex,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) -"dkf" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/bodybags,/obj/item/weapon/storage/box/syringes,/obj/item/weapon/storage/box/autoinjectors,/obj/item/weapon/storage/box/gloves,/obj/item/weapon/storage/firstaid/adv,/obj/item/bodybag/cryobag,/obj/item/weapon/reagent_containers/hypospray/CMO,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) +"dke" = (/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/wall/r_wall,/area/turret_protected/ai) +"dkf" = (/turf/simulated/wall,/area/aisat/maintenance) "dkg" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "specops_centcom_dock_inner"; locked = 1; name = "Shuttle Hatch"; req_access = null; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) "dkh" = (/obj/item/weapon/gun/projectile/automatic/m2411,/obj/item/ammo_box/magazine/m45,/obj/item/ammo_box/magazine/m45,/obj/item/ammo_box/magazine/m45,/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/clothing/head/helmet/space/deathsquad/beret,/obj/item/clothing/shoes/combat,/obj/item/clothing/under/syndicate/combat,/obj/item/clothing/gloves/combat,/obj/item/clothing/suit/space/deathsquad/officer,/obj/item/clothing/under/rank/centcom/captain,/obj/item/weapon/storage/box/handcuffs,/obj/item/weapon/storage/box/flashbangs,/obj/item/clothing/mask/gas,/obj/item/weapon/tank/emergency_oxygen/double,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/specops) "dki" = (/obj/machinery/recharge_station,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/specops) @@ -8646,9 +8646,9 @@ "dkn" = (/turf/simulated/shuttle/wall{icon_state = "swallc4"},/area/shuttle/escape/centcom) "dko" = (/obj/machinery/computer/shuttle_control/emergency,/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) "dkp" = (/turf/simulated/shuttle/wall{icon_state = "swallc3"},/area/shuttle/escape/centcom) -"dkq" = (/obj/structure/table/reinforced,/obj/item/device/aicard,/obj/item/weapon/pinpointer/advpinpointer,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) -"dkr" = (/obj/structure/rack,/obj/item/weapon/kitchenknife/combat,/obj/item/weapon/gun/energy/gun,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) -"dks" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/lockbox/loyalty,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) +"dkq" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/wall/r_wall,/area/aisat/maintenance) +"dkr" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/aisat/maintenance) +"dks" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/unsimulated/wall/fakeglass,/area/tdome) "dkt" = (/turf/unsimulated/wall/fakeglass{dir = 1; icon_state = "fakewindows"; tag = "icon-fakewindows (WEST)"},/area/centcom/specops) "dku" = (/turf/unsimulated/floor{tag = "icon-warning (NORTHWEST)"; icon_state = "warning"; dir = 9},/area/centcom/specops) "dkv" = (/turf/unsimulated/floor{tag = "icon-warning (NORTHEAST)"; icon_state = "warning"; dir = 5},/area/centcom/specops) @@ -8672,10 +8672,10 @@ "dkN" = (/obj/structure/shuttle/engine/propulsion{icon_state = "burst_l"; dir = 4},/turf/space,/area/shuttle/specops/centcom) "dkO" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/specops/centcom) "dkP" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "specops_shuttle_fore_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = null; req_access_txt = "13"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) -"dkQ" = (/turf/space,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/specops/centcom) +"dkQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/AIsattele) "dkR" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "CentComPort"; name = "Security Doors"; opacity = 0},/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/evac) -"dkS" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/evac) -"dkT" = (/obj/structure/table,/obj/machinery/door_control{desc = "A remote control switch for port-side blast doors."; icon_state = "doorctrl0"; id = "CentComPort"; name = "Security Doors"; pixel_y = -4; req_access_txt = "101"},/obj/machinery/door/window/southleft{dir = 1; name = "Security"; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/evac) +"dkS" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor,/area/centcom/evac) +"dkT" = (/obj/structure/table,/obj/machinery/door_control{desc = "A remote control switch for port-side blast doors."; icon_state = "doorctrl0"; id = "CentComPort"; name = "Security Doors"; pixel_y = -4; req_access_txt = "101"},/obj/machinery/door/window/southleft{dir = 1; name = "security checkpoint"; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/evac) "dkU" = (/turf/unsimulated/floor{icon_state = "green"; dir = 4},/area/centcom/evac) "dkV" = (/obj/structure/stool/bed/chair{dir = 1},/obj/structure/closet/walllocker/emerglocker{pixel_x = -28},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) "dkW" = (/obj/structure/stool/bed/chair{dir = 1},/obj/structure/closet/walllocker/emerglocker{pixel_x = 28},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) @@ -8688,8 +8688,8 @@ "dld" = (/obj/structure/stool/bed/chair,/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "specops_shuttle_fore"; pixel_x = 0; pixel_y = 25; req_access_txt = "101"; req_one_access_txt = "0"; tag_door = "specops_shuttle_fore_hatch"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) "dle" = (/obj/structure/stool/bed/chair,/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "specops_shuttle_port"; pixel_x = 25; pixel_y = -8; req_access_txt = "101"; req_one_access_txt = "0"; tag_door = "specops_shuttle_port_hatch"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) "dlf" = (/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/evac) -"dlg" = (/obj/machinery/door/window/westright{req_access_txt = "101"},/obj/structure/table/reinforced{icon_state = "reinf_tabledir"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/evac) -"dlh" = (/obj/machinery/door/window/eastleft{req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/evac) +"dlg" = (/obj/machinery/door/window/westright{name = "security checkpoint"; req_access_txt = "101"},/obj/structure/table,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/evac) +"dlh" = (/obj/machinery/door/window/eastleft{name = "security checkpoint"; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/evac) "dli" = (/turf/simulated/shuttle/wall{icon_state = "swall3"; dir = 2},/area/shuttle/escape/centcom) "dlj" = (/obj/machinery/computer/robotics,/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) "dlk" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) @@ -8698,7 +8698,7 @@ "dln" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "specops_shuttle_port_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = null; req_access_txt = "101"},/turf/simulated/shuttle/plating,/area/shuttle/specops/centcom) "dlo" = (/turf/simulated/shuttle/plating,/area/shuttle/specops/centcom) "dlp" = (/turf/unsimulated/floor{icon_state = "green"; dir = 10},/area/centcom/evac) -"dlq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/evac) +"dlq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{name = "plating"},/area/centcom/evac) "dlr" = (/obj/structure/stool/bed/chair,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/evac) "dls" = (/turf/simulated/shuttle/wall{icon_state = "swall12"; dir = 2},/area/shuttle/escape/centcom) "dlt" = (/turf/simulated/shuttle/wall{icon_state = "swall13"; dir = 2},/area/shuttle/escape/centcom) @@ -8707,11 +8707,11 @@ "dlw" = (/turf/space,/area/shuttle/escape_pod1/centcom) "dlx" = (/turf/space,/area/shuttle/escape_pod2/centcom) "dly" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) -"dlz" = (/turf/space,/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/shuttle/specops/centcom) +"dlz" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/AIsattele) "dlA" = (/obj/machinery/door/poddoor{id = "CentComPort"; name = "Security Doors"},/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/evac) -"dlB" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/evac) -"dlC" = (/obj/structure/table/reinforced{icon_state = "reinf_tabledir"},/obj/machinery/door/window/southleft{name = "Security"; req_access_txt = ""},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/evac) -"dlD" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/evac) +"dlB" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{name = "plating"},/area/centcom/evac) +"dlC" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{name = "plating"},/area/centcom/evac) +"dlD" = (/obj/structure/table,/obj/machinery/door/window/southleft{name = "security checkpoint"; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/evac) "dlE" = (/turf/unsimulated/floor{icon_state = "grass1"; name = "grass"},/area/centcom/evac) "dlF" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/unsimulated/floor{icon_state = "grass1"; name = "grass"},/area/centcom/evac) "dlG" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) @@ -8749,9 +8749,9 @@ "dmm" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0},/turf/unsimulated/wall,/area/centcom/evac) "dmn" = (/obj/item/flag/nt,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/evac) "dmo" = (/obj/effect/decal/warning_stripes/east,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/evac) -"dmp" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "centcom_dock_hatch"; locked = 1; name = "Arrival Airlock"; req_access = null; req_access_txt = "13"},/turf/unsimulated/floor{name = "plating"},/area/centcom/evac) +"dmp" = (/obj/machinery/door/airlock/external{aiControlDisabled = 1; frequency = 1379; hackProof = 1; icon_state = "door_locked"; id_tag = "centcom_dock_hatch"; locked = 1; name = "Arrival Airlock"; req_access = null; req_access_txt = "13"},/turf/unsimulated/floor{name = "plating"},/area/centcom/evac) "dmq" = (/turf/unsimulated/floor{name = "plating"},/area/centcom/evac) -"dmr" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "escape_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = null; req_access_txt = "13"},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"dmr" = (/obj/machinery/door/airlock/external{aiControlDisabled = 1; frequency = 1379; hackProof = 1; icon_state = "door_locked"; id_tag = "escape_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = null; req_access_txt = "13"},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) "dms" = (/turf/simulated/shuttle/plating,/area/centcom/evac) "dmt" = (/turf/simulated/shuttle/plating,/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"; dir = 2},/area/centcom/evac) "dmu" = (/turf/simulated/shuttle/floor,/turf/simulated/shuttle/wall{tag = "icon-swall_f9"; icon_state = "swall_f9"; dir = 2},/area/centcom/evac) @@ -8795,7 +8795,7 @@ "dng" = (/obj/machinery/computer/card,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/centcom/evac) "dnh" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/centcom/evac) "dni" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/centcom/evac) -"dnj" = (/obj/structure/table/reinforced,/obj/item/weapon/clipboard,/obj/item/weapon/stamp,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/centcom/evac) +"dnj" = (/obj/structure/table/reinforced,/obj/item/weapon/clipboard,/obj/item/weapon/stamp/granted,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/centcom/evac) "dnk" = (/obj/structure/closet/secure_closet/bar{req_access_txt = "25"},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/evac) "dnl" = (/obj/structure/table,/obj/item/weapon/lighter/zippo,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/evac) "dnm" = (/obj/machinery/door/airlock/centcom{name = "Rest Area"; opacity = 1; req_access_txt = "0"},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/evac) @@ -8921,7 +8921,7 @@ "dpC" = (/obj/structure/table,/obj/machinery/recharger{pixel_y = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "dpD" = (/turf/simulated/shuttle/wall{tag = "icon-swall3"; icon_state = "swall3"; dir = 2},/area/supply/dock) "dpE" = (/turf/simulated/shuttle/floor,/area/supply/dock) -"dpF" = (/obj/machinery/door/airlock/centcom{id_tag = "adminshuttle"; name = "General Access"; opacity = 1; req_access_txt = "101"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) +"dpF" = (/obj/machinery/telecomms/bus/preset_cent,/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/control) "dpG" = (/obj/item/stack/sheet/metal,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "dpH" = (/obj/item/stack/sheet/glass,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "dpI" = (/obj/machinery/microwave/upgraded,/obj/structure/table,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) @@ -8932,7 +8932,7 @@ "dpN" = (/obj/machinery/door/airlock/centcom{id_tag = "adminshuttle"; name = "Workshop"; opacity = 1; req_access_txt = "101"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "dpO" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad2"},/turf/simulated/shuttle/plating,/area/supply/dock) "dpP" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion_l (EAST)"; icon_state = "propulsion_l"; dir = 4},/turf/space,/area/shuttle/administration/centcom) -"dpQ" = (/obj/structure/shuttle/engine/heater{tag = "icon-heater (WEST)"; icon_state = "heater"; dir = 8},/obj/structure/window/plasmareinforced{color = "#d70000"; dir = 4},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/administration/centcom) +"dpQ" = (/obj/structure/grille,/obj/structure/window/plasmareinforced{color = "#FF0000"; dir = 1},/obj/machinery/door/poddoor/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "adminshuttleshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/window/plasmareinforced{color = "#FF0000"; dir = 8},/obj/structure/window/plasmareinforced{color = "#FF0000"; dir = 4},/turf/simulated/floor/plating,/area/shuttle/administration/centcom) "dpR" = (/obj/structure/stool,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "dpS" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "dpT" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) @@ -8952,11 +8952,11 @@ "dqh" = (/obj/machinery/vending/cigarette,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "dqi" = (/obj/structure/table/reinforced,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "dqj" = (/obj/machinery/computer/communications,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) -"dqk" = (/obj/structure/grille,/obj/structure/window/plasmareinforced{color = "#d70000"; dir = 1},/obj/machinery/door/poddoor/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "adminshuttleshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/window/plasmareinforced{color = "#d70000"; dir = 8},/obj/structure/window/plasmareinforced{color = "#d70000"; dir = 4},/turf/simulated/floor/plating,/area/shuttle/administration/centcom) +"dqk" = (/obj/structure/grille,/obj/machinery/door/poddoor/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "adminshuttleshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/window/plasmareinforced{color = "#FF0000"; dir = 8},/obj/structure/window/plasmareinforced{color = "#FF0000"; dir = 4},/turf/simulated/floor/plating,/area/shuttle/administration/centcom) "dql" = (/obj/machinery/door/airlock/centcom{id_tag = "adminshuttle"; name = "Bridge"; opacity = 1; req_access_txt = "101"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "dqm" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "dqn" = (/obj/machinery/computer/shuttle_control{req_access_txt = "101"; req_one_access_txt = "0"; shuttle_tag = "Administration"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) -"dqo" = (/obj/structure/grille,/obj/machinery/door/poddoor/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "adminshuttleshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/window/plasmareinforced{color = "#d70000"; dir = 8},/obj/structure/window/plasmareinforced{color = "#d70000"; dir = 4},/turf/simulated/floor/plating,/area/shuttle/administration/centcom) +"dqo" = (/obj/structure/grille,/obj/machinery/door/poddoor/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "adminshuttleshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/window/plasmareinforced{color = "#FF0000"; dir = 8},/obj/structure/window/plasmareinforced{color = "#FF0000"},/obj/structure/window/plasmareinforced{color = "#FF0000"; dir = 4},/turf/simulated/floor/plating,/area/shuttle/administration/centcom) "dqp" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad"},/turf/simulated/shuttle/plating,/area/supply/dock) "dqq" = (/obj/machinery/dna_scannernew/upgraded,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/administration/centcom) "dqr" = (/obj/machinery/computer/cloning,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/administration/centcom) @@ -8964,7 +8964,7 @@ "dqt" = (/obj/machinery/computer/scan_consolenew,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/administration/centcom) "dqu" = (/obj/structure/table/reinforced,/obj/machinery/door_control{id = "adminshuttleshutters"; name = "remote shutter control"; req_access_txt = "101"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "dqv" = (/obj/machinery/computer/card/centcom,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) -"dqw" = (/obj/structure/grille,/obj/machinery/door/poddoor/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "adminshuttleshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/window/plasmareinforced{color = "#d70000"; dir = 8},/obj/structure/window/plasmareinforced{color = "#d70000"},/obj/structure/window/plasmareinforced{color = "#d70000"; dir = 4},/turf/simulated/floor/plating,/area/shuttle/administration/centcom) +"dqw" = (/obj/structure/window/plasmareinforced{color = "#FF0000"; dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "dqx" = (/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/administration/centcom) "dqy" = (/obj/machinery/door/airlock/centcom{id_tag = "adminshuttle"; name = "Medbay"; opacity = 1; req_access_txt = "101"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "dqz" = (/turf/simulated/shuttle/wall{tag = "icon-swall7"; icon_state = "swall7"; dir = 2},/area/supply/dock) @@ -8973,7 +8973,7 @@ "dqC" = (/turf/simulated/shuttle/wall{tag = "icon-swall11"; icon_state = "swall11"; dir = 2},/area/supply/dock) "dqD" = (/obj/machinery/bodyscanner,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/administration/centcom) "dqE" = (/obj/machinery/body_scanconsole,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/administration/centcom) -"dqF" = (/obj/structure/window/plasmareinforced{color = "#d70000"; dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) +"dqF" = (/obj/structure/window/plasmareinforced{color = "#FF0000"; dir = 8},/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "dqG" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "dqH" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s5"; icon_state = "swall_s5"; dir = 2},/area/supply/dock) "dqI" = (/turf/simulated/shuttle/wall{tag = "icon-swall15"; icon_state = "swall15"; dir = 2},/area/supply/dock) @@ -8991,7 +8991,7 @@ "dqU" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-burst_r"; icon_state = "burst_r"},/turf/space,/area/supply/dock) "dqV" = (/obj/machinery/iv_drip,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/administration/centcom) "dqW" = (/obj/structure/table,/obj/item/weapon/storage/box/handcuffs,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) -"dqX" = (/obj/structure/window/plasmareinforced{color = "#d70000"; dir = 8},/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) +"dqX" = (/obj/structure/foodcart,/turf/simulated/floor{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) "dqY" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "dqZ" = (/obj/structure/table,/obj/item/weapon/bonegel,/obj/item/weapon/bonesetter,/obj/item/weapon/hemostat,/obj/item/weapon/cautery,/obj/item/weapon/surgicaldrill,/obj/item/weapon/circular_saw,/obj/item/weapon/scalpel,/obj/item/weapon/retractor,/obj/item/weapon/FixOVein,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/administration/centcom) "dra" = (/obj/machinery/optable,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/administration/centcom) @@ -9021,7 +9021,6 @@ "dry" = (/obj/structure/rack,/obj/item/clothing/gloves/black/thief{pixel_x = -3; pixel_y = 3},/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/rainbow{pixel_x = 3; pixel_y = -3},/obj/item/clothing/gloves/combat{pixel_x = -3; pixel_y = 3},/obj/item/clothing/gloves/color/latex,/obj/item/clothing/gloves/color/captain{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "drz" = (/obj/structure/rack,/obj/item/clothing/suit/armor/bulletproof{pixel_x = -3; pixel_y = 3},/obj/item/clothing/suit/armor/laserproof,/obj/item/clothing/suit/armor/vest{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "drA" = (/obj/mecha/combat/marauder/loaded,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) -"drB" = (/obj/mecha/combat/marauder/seraph,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "drC" = (/obj/mecha/combat/honker/loaded,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "drD" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/mech_bay_recharge_port/upgraded,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "drE" = (/turf/simulated/floor/mech_bay_recharge_floor,/area/admin) @@ -9059,7 +9058,7 @@ "dsk" = (/obj/item/weapon/storage/box/syringes,/obj/item/device/assembly/igniter,/obj/item/device/assembly/igniter,/obj/item/device/assembly/igniter,/obj/item/device/assembly/igniter,/obj/item/device/assembly/timer,/obj/item/device/assembly/timer,/obj/item/device/assembly/timer,/obj/item/device/assembly/timer,/obj/item/weapon/grenade/chem_grenade/large,/obj/item/weapon/grenade/chem_grenade/large,/obj/item/weapon/grenade/chem_grenade/large,/obj/item/weapon/grenade/chem_grenade/large,/obj/item/weapon/gun/syringe/rapidsyringe,/obj/item/weapon/reagent_containers/spray/chemsprayer,/obj/structure/closet,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "dsl" = (/turf/space,/turf/unsimulated/wall{dir = 2; icon = 'icons/turf/shuttle.dmi'; icon_state = "diagonalWall3"},/area/admin) "dsm" = (/obj/structure/rack,/obj/item/ammo_box/magazine/m10mm,/obj/item/ammo_box/magazine/m10mm,/obj/item/ammo_box/magazine/m10mm,/obj/item/ammo_box/magazine/m10mm,/obj/item/ammo_box/magazine/m10mm,/obj/item/ammo_box/magazine/m10mm,/obj/item/weapon/gun/projectile/automatic/pistol,/obj/item/weapon/gun/projectile/automatic/pistol{pixel_x = 3; pixel_y = -3},/obj/item/weapon/suppressor,/obj/item/weapon/suppressor{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) -"dsn" = (/obj/structure/rack,/obj/item/ammo_box/magazine/m12g,/obj/item/ammo_box/magazine/m12g,/obj/item/ammo_box/magazine/m12g/buckshot,/obj/item/ammo_box/magazine/m12g/buckshot,/obj/item/ammo_box/magazine/m12g/dragon,/obj/item/ammo_box/magazine/m12g/dragon,/obj/item/weapon/gun/projectile/automatic/bulldog,/obj/item/weapon/gun/projectile/automatic/bulldog{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) +"dsn" = (/obj/structure/rack,/obj/item/ammo_box/magazine/m12g,/obj/item/ammo_box/magazine/m12g,/obj/item/ammo_box/magazine/m12g/stun,/obj/item/ammo_box/magazine/m12g/stun,/obj/item/ammo_box/magazine/m12g/dragon,/obj/item/ammo_box/magazine/m12g/dragon,/obj/item/weapon/gun/projectile/automatic/bulldog,/obj/item/weapon/gun/projectile/automatic/bulldog{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "dso" = (/obj/structure/rack,/obj/item/ammo_box/magazine/smgm45,/obj/item/ammo_box/magazine/smgm45,/obj/item/ammo_box/magazine/smgm45,/obj/item/ammo_box/magazine/smgm45,/obj/item/ammo_box/magazine/smgm45,/obj/item/ammo_box/magazine/smgm45,/obj/item/weapon/gun/projectile/automatic/c20r,/obj/item/weapon/gun/projectile/automatic/c20r{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "dsp" = (/obj/structure/rack,/obj/item/ammo_box/magazine/m75,/obj/item/ammo_box/magazine/m75,/obj/item/ammo_box/magazine/m75,/obj/item/ammo_box/magazine/m75,/obj/item/ammo_box/magazine/m75,/obj/item/ammo_box/magazine/m75,/obj/item/weapon/gun/projectile/automatic/gyropistol,/obj/item/weapon/gun/projectile/automatic/gyropistol{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "dsq" = (/obj/structure/rack,/obj/item/ammo_box/magazine/m50,/obj/item/ammo_box/magazine/m50,/obj/item/ammo_box/magazine/m50,/obj/item/ammo_box/magazine/m50,/obj/item/ammo_box/magazine/m50,/obj/item/ammo_box/magazine/m50,/obj/item/weapon/gun/projectile/automatic/deagle,/obj/item/weapon/gun/projectile/automatic/deagle{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) @@ -9092,10 +9091,10 @@ "dsR" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/syndicate,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin) "dsS" = (/obj/structure/table,/obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/storage/pill_bottle/random_drug_bottle,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin) "dsT" = (/obj/structure/table,/obj/item/weapon/scalpel,/obj/item/weapon/bonesetter,/obj/item/weapon/bonegel,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) -"dsU" = (/obj/structure/table,/obj/item/weapon/kitchen/utensil/fork,/obj/item/weapon/lighter,/obj/item/weapon/handcuffs/cable/red,/obj/item/weapon/storage/box/mousetraps,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/pen,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) +"dsU" = (/obj/structure/table,/obj/item/weapon/kitchen/utensil/fork,/obj/item/weapon/lighter,/obj/item/weapon/restraints/handcuffs/cable/red,/obj/item/weapon/storage/box/mousetraps,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/pen,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "dsV" = (/obj/structure/table,/obj/item/weapon/tank/plasma,/obj/item/device/multitool,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "dsW" = (/obj/structure/table,/obj/random/toolbox,/obj/random/bomb_supply,/obj/item/weapon/storage/fancy/cigarettes,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) -"dsX" = (/obj/machinery/recharger/wallcharger{pixel_x = 30},/obj/structure/rack,/obj/item/weapon/gun/energy/pulse_rifle/M1911,/obj/item/weapon/gun/energy/pulse_rifle/M1911{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) +"dsX" = (/turf/simulated/mineral,/area/syndicate_depot) "dsY" = (/obj/structure/table,/obj/item/weapon/tank/oxygen/yellow,/obj/random/bomb_supply,/obj/item/clothing/under/rebeloutfit,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin) "dsZ" = (/obj/machinery/door/airlock/hatch{name = "Tool Storage"; req_access_txt = "0"},/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin) "dta" = (/obj/structure/table,/obj/item/weapon/FixOVein,/obj/item/weapon/retractor,/obj/item/weapon/cautery,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) @@ -9125,8 +9124,8 @@ "dty" = (/obj/machinery/computer/crew,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "dtz" = (/obj/machinery/computer/security{network = list("SS13","Telecomms","Research Outpost","Mining Outpost","ERT","CentCom","Thunderdome")},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "dtA" = (/obj/machinery/computer/rdservercontrol{badmin = 1; name = "Master R&D Server Controller"},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) -"dtB" = (/obj/structure/table,/obj/item/weapon/card/id/captains_spare,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) -"dtC" = (/obj/structure/table,/obj/item/weapon/card/id/silver,/obj/item/weapon/card/id/fluff/lifetime{pixel_x = 3; pixel_y = 3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) +"dtB" = (/obj/machinery/telecomms/hub/preset_cent,/turf/unsimulated/floor{icon_state = "green"; dir = 4},/area/centcom/control) +"dtC" = (/obj/machinery/telecomms/relay/preset/centcom,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/specops) "dtD" = (/obj/structure/table,/obj/item/weapon/card/id/centcom,/obj/item/weapon/card/id{pixel_x = 3; pixel_y = 3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "dtE" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'DANGER!'."; name = "\improper DANGER!"},/turf/unsimulated/wall{icon = 'icons/turf/shuttle.dmi'; icon_state = "wall3"},/area/admin) "dtF" = (/obj/structure/stool/bed/chair/comfy/black,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/admin) @@ -9150,7 +9149,7 @@ "dtX" = (/obj/machinery/computer/message_monitor,/obj/item/weapon/paper/monitorkey,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "dtY" = (/obj/machinery/computer/atmos_alert,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "dtZ" = (/obj/machinery/computer/secure_data,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) -"dua" = (/obj/machinery/account_database{name = "Admin Accounts database"},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) +"dua" = (/obj/machinery/telecomms/receiver/preset_cent,/turf/unsimulated/floor{icon_state = "green"; dir = 10},/area/centcom/control) "dub" = (/obj/structure/table,/obj/item/weapon/gun/projectile/automatic/pistol,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "duc" = (/obj/structure/table,/obj/machinery/door_control{desc = "A remote control switch to lock down external access to the admin room."; icon_state = "doorctrl0"; id = "ADMINLOCKDOWN"; name = "Lockdown"; pixel_y = 0; req_access_txt = "0"},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "dud" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/drinks/cans/beer{desc = "Contains the hopes and dreams of banned griffons."; name = "adminbooze"; pixel_x = 3; pixel_y = -3},/obj/item/weapon/reagent_containers/food/drinks/cans/beer{desc = "Contains the hopes and dreams of banned griffons."; name = "adminbooze"; pixel_x = -3},/obj/item/weapon/storage/fancy/cigarettes/syndicate,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) @@ -9249,7 +9248,7 @@ "dvS" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows (WEST)"; icon_state = "fakewindows"; dir = 8},/area) "dvT" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows2 (WEST)"; icon_state = "fakewindows2"; dir = 8},/area) "dvU" = (/obj/machinery/door/airlock/command{name = "Thunderdome Administration"; req_access = null; req_access_txt = "102"},/turf/simulated/floor,/area/tdome) -"dvV" = (/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden,/turf/unsimulated/wall/fakeglass,/area/tdome) +"dvV" = (/turf/simulated/wall/r_wall,/area/traitor/hall) "dvW" = (/obj/structure/rack,/obj/item/clothing/under/color/green,/obj/item/clothing/shoes/brown,/obj/item/clothing/suit/armor/vest,/obj/item/clothing/head/helmet/swat,/obj/item/weapon/gun/energy/laser,/obj/item/weapon/shield/energy,/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) "dvX" = (/turf/unsimulated/floor{tag = "icon-redyellowfull (NORTHEAST)"; icon_state = "redyellowfull"; dir = 5},/area/tdome/tdomeadmin) "dvY" = (/obj/structure/stool/bed/chair{dir = 1},/obj/effect/landmark{name = "tdomeadmin"},/turf/unsimulated/floor{tag = "icon-redyellowfull (NORTHEAST)"; icon_state = "redyellowfull"; dir = 5},/area/tdome/tdomeadmin) @@ -9306,7 +9305,7 @@ "dwX" = (/obj/structure/table,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) "dwY" = (/turf/simulated/shuttle/wall{tag = "icon-swall3"; icon_state = "swall3"; dir = 2},/area/derelict/ship) "dwZ" = (/obj/item/device/multitool,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) -"dxa" = (/obj/item/weapon/cell{charge = 100; maxcharge = 15000},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) +"dxa" = (/obj/item/weapon/stock_parts/cell{charge = 100; maxcharge = 15000},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) "dxb" = (/obj/machinery/door/unpowered/shuttle,/turf/simulated/floor/plating,/area/derelict/ship) "dxc" = (/turf/simulated/shuttle/plating,/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"; dir = 2},/area/derelict/ship) "dxd" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-burst_l (WEST)"; icon_state = "burst_l"; dir = 8},/turf/space,/area/derelict/ship) @@ -9465,7 +9464,7 @@ "dAa" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor{tag = "icon-vault (NORTHEAST)"; icon_state = "vault"; dir = 5},/area/tcommsat/chamber) "dAb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/tcommsat/computer) "dAc" = (/obj/machinery/door/airlock/hatch{name = "Telecoms Lounge"; req_access_txt = "61"},/turf/simulated/floor{tag = "icon-vault (NORTHEAST)"; icon_state = "vault"; dir = 5},/area/tcommsat/computer) -"dAd" = (/obj/machinery/turret{lasers = 1; lasertype = 2},/turf/simulated/floor/plating/airless,/area/turret_protected/tcomsat) +"dAd" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall/r_wall,/area/traitor/kitchen) "dAe" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/lattice,/turf/space,/area/turret_protected/tcomsat) "dAf" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/tcommsat/chamber) "dAg" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/tcommsat/chamber) @@ -9566,13 +9565,13 @@ "dBX" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/space,/area/turret_protected/tcomsat) "dBY" = (/obj/structure/window/reinforced,/obj/structure/lattice,/obj/machinery/light{dir = 1},/turf/space,/area/turret_protected/tcomsat) "dBZ" = (/turf/simulated/wall/r_wall,/area/turret_protected/tcomfoyer) -"dCa" = (/obj/machinery/turret{dir = 4},/obj/structure/sign/securearea{desc = "A warning sign which reads 'LETHAL TURRETS'. Enter at your own risk!"; name = "LETHAL TURRETS"; pixel_x = -32; pixel_y = 0},/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/turret_protected/tcomfoyer) +"dCa" = (/turf/simulated/wall/r_wall,/area/traitor/kitchen) "dCb" = (/obj/machinery/power/apc{dir = 1; name = "Telecoms Sat. Foyer APC"; pixel_x = 1; pixel_y = 26},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor{tag = "icon-warningcorner (EAST)"; icon_state = "warningcorner"; dir = 4},/area/turret_protected/tcomfoyer) "dCc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{tag = "icon-warningcorner (WEST)"; icon_state = "warningcorner"; dir = 8},/area/turret_protected/tcomfoyer) -"dCd" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/turretid{ailock = 1; control_area = "\improper Telecoms Satellite"; desc = "A firewall prevents AIs from interacting with this device."; icon_state = "control_kill"; lethal = 1; name = "Telecoms lethal turret control"; pixel_y = 30; req_access = list(61)},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/camera{c_tag = "Telecomms Foyer"; dir = 2; network = list("Telecomms")},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/turret_protected/tcomfoyer) +"dCd" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/turretid/lethal{ailock = 1; check_synth = 1; control_area = "\improper Telecoms Satellite"; desc = "A firewall prevents AI's from interacting with this device."; icon_state = "control_kill"; lethal = 1; name = "Telecomms Lethal Turret Control"; pixel_y = 30; req_access = list(61)},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/camera{c_tag = "Telecomms Foyer"; dir = 2; network = list("Telecomms")},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/turret_protected/tcomfoyer) "dCe" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/turf/simulated/floor{tag = "icon-warningcorner (EAST)"; icon_state = "warningcorner"; dir = 4},/area/turret_protected/tcomfoyer) "dCf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/status_display{pixel_x = 0; pixel_y = 32},/turf/simulated/floor{tag = "icon-warningcorner (WEST)"; icon_state = "warningcorner"; dir = 8},/area/turret_protected/tcomfoyer) -"dCg" = (/obj/machinery/turret{dir = 8},/obj/structure/sign/securearea{desc = "A warning sign which reads 'LETHAL TURRETS'. Enter at your own risk!"; name = "LETHAL TURRETS"; pixel_x = 32; pixel_y = 0},/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/turret_protected/tcomfoyer) +"dCg" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/empty) "dCh" = (/obj/structure/window/reinforced,/obj/machinery/light{dir = 1},/turf/space,/area/turret_protected/tcomsat) "dCi" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/space,/area/turret_protected/tcomsat) "dCj" = (/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor{tag = "icon-vault (NORTHEAST)"; icon_state = "vault"; dir = 5},/area/turret_protected/tcomsat) @@ -9606,7 +9605,7 @@ "dCL" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/sign/electricshock,/turf/simulated/wall/r_wall,/area/tcommsat/entrance) "dCM" = (/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = 20},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor,/area/tcommsat/entrance) "dCN" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/tcommsat/entrance) -"dCO" = (/obj/machinery/turretid{ailock = 1; control_area = "\improper Telecoms Foyer"; desc = "A firewall prevents AIs from interacting with this device."; icon_state = "control_stun"; lethal = 0; name = "Telecoms Foyer turret control"; pixel_y = 30; req_access = list(61)},/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor,/area/tcommsat/entrance) +"dCO" = (/obj/machinery/turretid/stun{ailock = 1; check_synth = 1; control_area = "\improper Telecoms Foyer"; desc = "A firewall prevents AI's from interacting with this device."; name = "Telecoms Foyer Turret Control"; pixel_y = 30; req_access = list(61)},/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor,/area/tcommsat/entrance) "dCP" = (/obj/structure/sign/electricshock,/turf/simulated/wall/r_wall,/area/tcommsat/entrance) "dCQ" = (/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/tcommsat/entrance) "dCR" = (/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/power/monitor{name = "telecoms power monitoring"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor{icon_state = "bot"},/area/tcommsat/entrance) @@ -9634,7 +9633,7 @@ "dDn" = (/obj/machinery/power/apc{dir = 1; name = "Telecoms Sat. Teleporter APC"; pixel_x = 1; pixel_y = 26},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor,/area/tcommsat/entrance) "dDo" = (/obj/structure/sign/vacuum,/turf/simulated/wall/r_wall,/area/tcommsat/entrance) "dDp" = (/obj/machinery/atmospherics/pipe/tank/air,/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/tcommsat/entrance) -"dDq" = (/obj/item/weapon/cell,/turf/simulated/floor,/area/tcommsat/entrance) +"dDq" = (/obj/item/weapon/stock_parts/cell,/turf/simulated/floor,/area/tcommsat/entrance) "dDr" = (/turf/simulated/floor,/area/tcommsat/entrance) "dDs" = (/obj/structure/closet/malf/suits,/turf/simulated/floor,/area/tcommsat/entrance) "dDt" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1381; master_tag = "telecoms_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = "13"},/turf/simulated/floor/plating/airless,/area) @@ -9662,13 +9661,13 @@ "dDP" = (/obj/item/weapon/shard{icon_state = "medium"},/turf/simulated/floor/plating/airless,/area/AIsattele) "dDQ" = (/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating/airless,/area/AIsattele) "dDR" = (/obj/structure/rack,/obj/item/clothing/gloves/yellow,/turf/simulated/floor/plating/airless,/area/AIsattele) -"dDS" = (/obj/item/weapon/cell,/turf/simulated/floor/plating/airless,/area/AIsattele) +"dDS" = (/obj/item/weapon/stock_parts/cell,/turf/simulated/floor/plating/airless,/area/AIsattele) "dDT" = (/obj/item/device/radio/beacon,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating/airless,/area/AIsattele) "dDU" = (/obj/item/device/flashlight,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating/airless,/area/AIsattele) "dDV" = (/obj/machinery/door/airlock/external,/turf/simulated/floor/plating/airless,/area/AIsattele) "dDW" = (/obj/structure/lattice,/turf/space,/area/AIsattele) "dDX" = (/obj/structure/closet,/turf/simulated/floor/plating/airless,/area/AIsattele) -"dDY" = (/obj/machinery/door/airlock/external,/turf/simulated/floor/plating/airless,/area) +"dDY" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/traitor/empty) "dDZ" = (/obj/effect/decal/cleanable/blood/old,/turf/simulated/floor/plating/airless,/area/AIsattele) "dEa" = (/obj/item/weapon/storage/toolbox/electrical{pixel_x = 1; pixel_y = -1},/turf/simulated/floor/plating/airless,/area/AIsattele) "dEb" = (/turf/simulated/wall,/area/constructionsite/maintenance) @@ -10048,7 +10047,7 @@ "dLl" = (/obj/structure/transit_tube{icon_state = "S-NE"},/obj/structure/lattice,/turf/space,/area) "dLm" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/research_outpost/maintstore1) "dLn" = (/obj/structure/closet/hydrant{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plating,/area/research_outpost/maintstore1) -"dLo" = (/obj/structure/table,/obj/item/device/analyzer/plant_analyzer,/obj/item/weapon/cell,/obj/item/stack/cable_coil/random,/obj/item/stack/cable_coil/random,/obj/machinery/light/small{dir = 1},/obj/machinery/alarm{dir = 2; pixel_y = 25},/turf/simulated/floor/plating,/area/research_outpost/maintstore1) +"dLo" = (/obj/structure/table,/obj/item/device/analyzer/plant_analyzer,/obj/item/weapon/stock_parts/cell,/obj/item/stack/cable_coil/random,/obj/item/stack/cable_coil/random,/obj/machinery/light/small{dir = 1},/obj/machinery/alarm{dir = 2; pixel_y = 25},/turf/simulated/floor/plating,/area/research_outpost/maintstore1) "dLp" = (/obj/structure/transit_tube{icon_state = "D-SW"},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1) "dLq" = (/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1) "dLr" = (/obj/structure/transit_tube{icon_state = "NE-SW"},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1) @@ -10336,7 +10335,7 @@ "dQN" = (/obj/effect/decal/remains/xeno,/turf/simulated/floor/airless{icon_state = "damaged2"},/area/mine/abandoned) "dQO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/hallway) "dQP" = (/obj/structure/table,/obj/item/weapon/folder,/turf/simulated/floor/wood,/area/research_outpost/hallway) -"dQQ" = (/obj/structure/table,/obj/item/device/camera,/obj/item/weapon/stamp,/turf/simulated/floor/wood,/area/research_outpost/hallway) +"dQQ" = (/obj/structure/table,/obj/item/device/camera,/obj/item/weapon/stamp/granted,/turf/simulated/floor/wood,/area/research_outpost/hallway) "dQR" = (/turf/simulated/floor/wood,/area/research_outpost/hallway) "dQS" = (/obj/machinery/vending/snack,/obj/machinery/light{dir = 4},/turf/simulated/floor/wood,/area/research_outpost/hallway) "dQT" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/door/firedoor/border_only{dir = 4; layer = 2.6; name = "Firelock"},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) @@ -10987,7 +10986,7 @@ "edo" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "labor_camp_north_outer"; locked = 1; name = "Labor Camp Airlock"; opacity = 1; req_access_txt = "2"},/turf/simulated/floor{icon_state = "floorgrime"; temperature = 273.15},/area/mine/laborcamp) "edp" = (/obj/machinery/light/small{dir = 1},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "labor_camp_north_sensor"; pixel_x = -8; pixel_y = 30},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "labor_camp_north_pump"},/obj/machinery/door_control{id = "Labor"; name = "Labor Camp Lockdown"; pixel_x = 0; pixel_y = -28; req_access_txt = "2"},/obj/machinery/embedded_controller/radio/airlock/docking_port_multi{id_tag = "labor_camp_north_airlock"; master_tag = "labor_camp_dock"; pixel_y = 30; req_access_txt = "2"; req_one_access_txt = "0"; tag_airpump = "labor_camp_north_pump"; tag_chamber_sensor = "labor_camp_north_sensor"; tag_exterior_door = "labor_camp_north_outer"; tag_interior_door = "labor_camp_north_inner"},/turf/simulated/floor{icon_state = "floorgrime"; temperature = 273.15},/area/mine/laborcamp) "edq" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "labor_camp_north_inner"; locked = 1; name = "Labor Camp Airlock"; opacity = 1; req_access_txt = "2"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"; temperature = 273.15},/area/mine/laborcamp) -"edr" = (/obj/machinery/door/poddoor/preopen{id = "Labor"; name = "labor camp blast door"},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "labor_camp_north_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = 25; req_access_txt = "2"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 10; initialize_directions = 10},/turf/simulated/floor{icon_state = "floorgrime"; temperature = 273.15},/area/mine/laborcamp) +"edr" = (/obj/machinery/door/poddoor/preopen{id = "Labor"; name = "labor camp blast door"},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "labor_camp_north_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = 25; req_access_txt = "2"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 10; initialize_directions = 10},/obj/machinery/door/airlock/glass_security{name = "Labor Camp Shuttle Cockpit"; req_access_txt = "2"},/turf/simulated/floor{icon_state = "floorgrime"; temperature = 273.15},/area/mine/laborcamp) "eds" = (/turf/simulated/floor,/area/mine/laborcamp) "edt" = (/obj/machinery/mineral/processing_unit_console{machinedir = 6},/turf/simulated/wall,/area/mine/laborcamp) "edu" = (/obj/structure/plasticflaps,/obj/machinery/conveyor{dir = 2; id = "gulag"},/obj/machinery/mineral/input,/turf/simulated/floor{icon_state = "floorgrime"; temperature = 273.15},/area/mine/laborcamp) @@ -11198,7 +11197,7 @@ "ehr" = (/obj/machinery/computer/mech_bay_power_console,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"; tag = "icon-asteroidfloor"},/area/mine/west_outpost) "ehs" = (/obj/structure/disposalpipe/segment,/obj/structure/sign/deathsposal,/turf/simulated/wall,/area/mine/living_quarters) "eht" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/living_quarters) -"ehu" = (/obj/structure/table/reinforced,/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 8},/area/mine/explored) +"ehu" = (/obj/structure/table/reinforced,/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 8},/area/mine/explored) "ehv" = (/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) "ehw" = (/obj/machinery/mining/brace,/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) "ehx" = (/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 4},/area/mine/explored) @@ -11418,7 +11417,7 @@ "elD" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/machinery/door/airlock/glass_medical{id_tag = null; name = "Infirmary"; req_access_txt = "0"},/obj/machinery/door/firedoor/border_only{dir = 4; layer = 2.6; name = "Firelock"},/turf/simulated/floor{icon_state = "white"},/area/mine/living_quarters) "elE" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"},/turf/simulated/wall,/area/mine/living_quarters) "elF" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/door/airlock/maintenance{name = "Mining Station Maintenance"; req_access_txt = "48"},/obj/machinery/door/firedoor/border_only{dir = 4; layer = 2.6; name = "Firelock"},/turf/simulated/floor/plating,/area/mine/living_quarters) -"elG" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor/plating,/area) +"elG" = (/turf/simulated/wall/r_wall,/area/traitor/empty) "elH" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "mining_west_inner"; locked = 1; name = "Mining External Access"; req_access = null; req_access_txt = null},/turf/simulated/floor,/area/mine/living_quarters) "elI" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/living_quarters) "elJ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/production) @@ -11683,7 +11682,7 @@ "eqI" = (/obj/machinery/door/airlock/glass,/turf/simulated/floor,/area/derelict/bridge/access) "eqJ" = (/turf/simulated/wall/r_wall,/area/derelict/singularity_engine) "eqK" = (/obj/structure/window/reinforced,/turf/simulated/floor,/area/derelict/bridge/access) -"eqL" = (/obj/machinery/door/window,/turf/simulated/floor,/area/derelict/bridge/access) +"eqL" = (/obj/machinery/door/window{dir = 2},/turf/simulated/floor,/area/derelict/bridge/access) "eqM" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/cable,/obj/structure/window/reinforced,/turf/simulated/floor,/area/derelict/bridge/access) "eqN" = (/turf/simulated/wall,/area/derelict/bridge) "eqO" = (/obj/structure/sign/electricshock,/turf/simulated/wall/r_wall,/area/derelict/singularity_engine) @@ -11733,7 +11732,7 @@ "erG" = (/obj/machinery/bot/secbot/buzzsky,/turf/simulated/floor,/area/derelict/bridge) "erH" = (/obj/structure/table,/obj/item/device/paicard,/turf/simulated/floor,/area/derelict/bridge) "erI" = (/obj/structure/stool,/turf/simulated/floor,/area/derelict/bridge) -"erJ" = (/obj/structure/table,/obj/item/weapon/cell,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor,/area/derelict/bridge) +"erJ" = (/obj/structure/table,/obj/item/weapon/stock_parts/cell,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor,/area/derelict/bridge) "erK" = (/obj/item/weapon/storage/toolbox/syndicate,/turf/simulated/floor/airless{icon_state = "damaged2"},/area/derelict/singularity_engine) "erL" = (/obj/item/stack/cable_coil/cut,/turf/simulated/floor/airless{icon_state = "damaged4"},/area/derelict/singularity_engine) "erM" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor,/area/derelict/bridge/access) @@ -11767,7 +11766,7 @@ "eso" = (/obj/item/weapon/shard{icon_state = "small"},/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) "esp" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) "esq" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) -"esr" = (/obj/machinery/door/window,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/derelict/bridge/access) +"esr" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/window{dir = 2},/turf/simulated/floor,/area/derelict/bridge/access) "ess" = (/turf/simulated/wall/r_wall,/area/derelict/bridge) "est" = (/obj/machinery/door/window{dir = 2; name = "Captain's Quarters"; req_access_txt = "20"},/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/derelict/bridge) "esu" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) @@ -11779,7 +11778,7 @@ "esA" = (/obj/structure/table,/obj/item/device/aicard,/turf/simulated/floor/airless,/area/derelict/bridge/access) "esB" = (/obj/structure/table,/obj/machinery/light/small{dir = 1},/turf/simulated/floor/airless,/area/derelict/bridge/access) "esC" = (/obj/structure/table,/obj/item/stack/cable_coil{pixel_x = 3; pixel_y = -7},/turf/simulated/floor/airless,/area/derelict/bridge/access) -"esD" = (/obj/structure/table,/obj/item/weapon/cell{charge = 100; maxcharge = 15000},/turf/simulated/floor/airless,/area/derelict/bridge/access) +"esD" = (/obj/structure/table,/obj/item/weapon/stock_parts/cell{charge = 100; maxcharge = 15000},/turf/simulated/floor/airless,/area/derelict/bridge/access) "esE" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/airless,/area/derelict/bridge/access) "esF" = (/obj/structure/girder,/turf/simulated/floor/plating/airless,/area) "esG" = (/turf/simulated/floor/airless{icon_state = "circuit"},/area/derelict/singularity_engine) @@ -11833,7 +11832,7 @@ "etC" = (/turf/simulated/floor/airless{icon_state = "floorscorched2"},/area) "etD" = (/turf/simulated/floor/airless{icon_state = "damaged2"},/area) "etE" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) -"etF" = (/obj/machinery/door/window,/turf/simulated/floor/plating/airless,/area/derelict/hallway/primary) +"etF" = (/obj/machinery/door/window{dir = 2},/turf/simulated/floor/plating/airless,/area/derelict/hallway/primary) "etG" = (/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area) "etH" = (/obj/item/weapon/shard{icon_state = "medium"},/turf/simulated/floor/airless{icon_state = "damaged2"},/area/derelict/singularity_engine) "etI" = (/obj/structure/grille{density = 0; icon_state = "brokengrille"},/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) @@ -11962,7 +11961,7 @@ "ewb" = (/obj/structure/table,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor{dir = 1; icon_state = "chapel"},/area/derelict/medical/chapel) "ewc" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor{dir = 4; icon_state = "chapel"},/area/derelict/medical/chapel) "ewd" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor{dir = 1; icon_state = "chapel"},/area/derelict/medical/chapel) -"ewe" = (/obj/machinery/door/window,/turf/simulated/floor/airless,/area/derelict/medical/chapel) +"ewe" = (/obj/machinery/door/window{dir = 2},/turf/simulated/floor/airless,/area/derelict/medical/chapel) "ewf" = (/obj/machinery/door/window/southleft,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/airless{icon_state = "white"},/area/derelict/medical) "ewg" = (/obj/machinery/door/window/southright,/turf/simulated/floor/airless{icon_state = "white"},/area/derelict/medical) "ewh" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/airless,/area/derelict/hallway/primary) @@ -12001,7 +12000,7 @@ "ewO" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/airless,/area/derelict/hallway/primary) "ewP" = (/obj/structure/girder,/turf/simulated/floor/airless,/area/derelict/hallway/primary) "ewQ" = (/obj/machinery/portable_atmospherics/pump,/turf/simulated/floor,/area/derelict/arrival) -"ewR" = (/obj/machinery/door/window,/turf/simulated/floor/airless,/area/derelict/hallway/primary) +"ewR" = (/obj/machinery/door/window{dir = 2},/turf/simulated/floor/airless,/area/derelict/hallway/primary) "ewS" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/airless,/area/derelict/hallway/primary) "ewT" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/turf/simulated/floor/airless,/area/derelict/hallway/primary) "ewU" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/airless,/area/derelict/hallway/primary) @@ -12018,7 +12017,7 @@ "exf" = (/obj/structure/window/basic{dir = 1},/turf/simulated/floor/plating,/area/derelict/arrival) "exg" = (/obj/machinery/light{dir = 1},/turf/simulated/floor,/area/derelict/arrival) "exh" = (/obj/structure/table,/turf/simulated/floor/airless,/area/derelict/hallway/primary) -"exi" = (/obj/structure/table,/obj/item/weapon/cell,/turf/simulated/floor/airless,/area/derelict/hallway/primary) +"exi" = (/obj/structure/table,/obj/item/weapon/stock_parts/cell,/turf/simulated/floor/airless,/area/derelict/hallway/primary) "exj" = (/obj/machinery/vending/sovietsoda,/turf/simulated/floor/airless,/area/derelict/hallway/primary) "exk" = (/obj/structure/cable,/obj/machinery/power/apc{dir = 0; name = "Worn-out APC"; pixel_y = -24},/turf/simulated/floor/airless,/area/derelict/hallway/primary) "exl" = (/obj/structure/table,/turf/simulated/floor/airless,/area) @@ -12121,7 +12120,7 @@ "eze" = (/obj/item/weapon/paper/russiantraitorobj,/turf/simulated/floor/airless{icon_state = "damaged2"},/area/derelict/bridge/ai_upload) "ezf" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating/airless,/area/AIsattele) "ezg" = (/obj/item/stack/rods,/turf/simulated/floor/plating/airless,/area/derelict/hallway/secondary) -"ezh" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"},/turf/simulated/floor/airless,/area) +"ezh" = (/obj/machinery/door/window{dir = 8},/turf/simulated/floor/airless,/area/derelict/bridge/ai_upload) "ezi" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/light/small,/turf/simulated/floor/airless,/area/derelict/bridge/ai_upload) "ezj" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"},/turf/simulated/floor/airless,/area/derelict/bridge/ai_upload) "ezk" = (/obj/structure/closet/crate,/obj/item/device/aicard,/obj/item/device/multitool,/obj/item/weapon/weldingtool,/obj/item/weapon/wrench,/obj/item/weapon/circuitboard/teleporter,/turf/simulated/floor/plating/airless,/area/AIsattele) @@ -12149,7 +12148,7 @@ "ezG" = (/obj/machinery/teleport/station,/turf/simulated/floor/airless,/area/derelict/teleporter) "ezH" = (/obj/machinery/teleport/hub,/turf/simulated/floor/airless,/area/derelict/teleporter) "ezI" = (/obj/machinery/light_construct/small{dir = 4},/turf/simulated/floor/plating/airless,/area/derelict/teleporter) -"ezJ" = (/obj/structure/table,/obj/item/weapon/cell{charge = 100; maxcharge = 15000},/turf/simulated/floor/airless,/area/derelict/teleporter) +"ezJ" = (/obj/structure/table,/obj/item/weapon/stock_parts/cell{charge = 100; maxcharge = 15000},/turf/simulated/floor/airless,/area/derelict/teleporter) "ezK" = (/turf/simulated/floor/airless{icon_state = "damaged4"},/area/derelict/teleporter) "ezL" = (/obj/machinery/power/apc{dir = 0; name = "Worn-out APC"; pixel_y = -24},/turf/simulated/floor/airless,/area/derelict/teleporter) "ezM" = (/turf/simulated/floor/plating/airless/asteroid,/area/syndicate_depot) @@ -12216,11 +12215,11 @@ "eAV" = (/obj/machinery/light/small{dir = 4},/obj/machinery/airlock_sensor{frequency = 1479; id_tag = "traitor_station_sensor"; pixel_x = 25; pixel_y = -5},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1479; id_tag = "traitor_station_pump"},/obj/structure/closet/emcloset,/turf/simulated/floor{icon_state = "dark"},/area/traitor/hall) "eAW" = (/obj/structure/disposaloutlet{dir = 1},/obj/structure/disposalpipe/trunk,/turf/simulated/floor/plating/airless,/area) "eAX" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 32; pixel_y = 0},/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor{icon_state = "dark"},/area/traitor/hall) -"eAY" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area) -"eAZ" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/turf/simulated/floor/plating,/area) -"eBa" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area) -"eBb" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/floor/plating,/area) -"eBc" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/floor/plating,/area) +"eAY" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/traitor/kitchen) +"eAZ" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/kitchen) +"eBa" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/traitor/kitchen) +"eBb" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/empty) +"eBc" = (/turf/simulated/wall/r_wall,/area/traitor/chem) "eBd" = (/obj/machinery/door/airlock/external{frequency = 1479; icon_state = "door_locked"; id_tag = "traitor_station_inner"; locked = 1; name = "Syndicate Station Interior Access"; req_access = null; req_access_txt = null},/turf/simulated/floor{icon_state = "dark"},/area/traitor/hall) "eBe" = (/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/power/apc{dir = 1; pixel_y = 24},/obj/structure/disposalpipe/segment,/obj/structure/stool/bed/chair/office/light{dir = 4},/obj/machinery/alarm{dir = 4; hidden = 1; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor,/area/traitor/kitchen) "eBf" = (/obj/structure/table,/obj/item/candle,/turf/simulated/floor,/area/traitor/kitchen) @@ -12229,7 +12228,7 @@ "eBi" = (/obj/machinery/gibber,/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/floor,/area/traitor/kitchen) "eBj" = (/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/power/apc{dir = 1; pixel_y = 24},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/empty) "eBk" = (/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/empty) -"eBl" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/turf/simulated/floor/plating,/area) +"eBl" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/traitor/chem) "eBm" = (/obj/structure/table,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/chem) "eBn" = (/obj/machinery/chem_master,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/chem) "eBo" = (/obj/structure/table,/obj/machinery/reagentgrinder,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/chem) @@ -12279,10 +12278,10 @@ "eCg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor,/area/traitor/kitchen) "eCh" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/traitor/kitchen) "eCi" = (/obj/machinery/alarm{dir = 4; hidden = 1; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/empty) -"eCj" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area) -"eCk" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/turf/simulated/floor/plating,/area) -"eCl" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/floor/plating,/area) -"eCm" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area) +"eCj" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/chem) +"eCk" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/chem) +"eCl" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/empty) +"eCm" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/chem) "eCn" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/hall) "eCo" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/hall) "eCp" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/hall) @@ -12333,15 +12332,15 @@ "eDi" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/hall) "eDj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/hall) "eDk" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/hall) -"eDl" = (/obj/machinery/door/airlock/glass,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/hall) +"eDl" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/traitor/empty) "eDm" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/tox) "eDn" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/tox) "eDo" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/tox) "eDp" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/traitor/tox) "eDq" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/tox) "eDr" = (/obj/machinery/atmospherics/binary/pump/highcap{dir = 8},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/tox) -"eDs" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/floor/plating,/area) -"eDt" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/space,/area/traitor/tox) +"eDs" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/traitor/chem) +"eDt" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/chem) "eDu" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/wall/r_wall,/area/traitor/tox) "eDv" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/floor/engine,/area/traitor/tox) "eDw" = (/obj/machinery/atmospherics/pipe/vent{dir = 8},/turf/simulated/floor/engine,/area/traitor/tox) @@ -12350,7 +12349,7 @@ "eDz" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/rnd) "eDA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/rnd) "eDB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/rnd) -"eDC" = (/obj/machinery/door/airlock/multi_tile/glass{dir = 3; name = "Research and Development"; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor/multi_tile{dir = 3; layer = 2.6},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/hall) +"eDC" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/chem) "eDD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/hall) "eDE" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/hall) "eDF" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/hall) @@ -12361,7 +12360,7 @@ "eDK" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/traitor/tox) "eDL" = (/obj/machinery/atmospherics/binary/pump/highcap{dir = 1},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/tox) "eDM" = (/obj/machinery/computer/general_air_control{frequency = 1222; name = "Bomb Mix Monitor"; sensors = list("burn_sensor" = "Burn Mix")},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/tox) -"eDN" = (/turf/space,/area/traitor/tox) +"eDN" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/traitor/empty) "eDO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/traitor/tox) "eDP" = (/obj/machinery/igniter{icon_state = "igniter0"; id = "SyndieToxinsIgnitor"; on = 0},/turf/simulated/floor/engine,/area/traitor/tox) "eDQ" = (/obj/machinery/air_sensor{id_tag = "burn_sensor"},/turf/simulated/floor/engine,/area/traitor/tox) @@ -12370,15 +12369,15 @@ "eDT" = (/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/hall) "eDU" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/hall) "eDV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/hall) -"eDW" = (/obj/machinery/door/firedoor/multi_tile/triple{dir = 3; layer = 2.6},/obj/machinery/door/airlock/glass,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/hall) +"eDW" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/traitor/rnd) "eDX" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/tox) "eDY" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/tox) "eDZ" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/tox) "eEa" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 8},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/tox) "eEb" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor/plating,/area/traitor/atmos) "eEc" = (/obj/machinery/atmospherics/binary/pump/highcap{dir = 4},/obj/machinery/ignition_switch{id = "SyndieToxinsIgnitor"; layer = 3.3; pixel_x = 21; pixel_y = 8},/obj/machinery/door_control{id = "SyndieToxVent"; layer = 3.3; pixel_x = 22; pixel_y = -8},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/tox) -"eEd" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; level = 2},/turf/simulated/floor/plating,/area) -"eEe" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; level = 2},/turf/space,/area/traitor/tox) +"eEd" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/rnd) +"eEe" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/rnd) "eEf" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; level = 2},/turf/simulated/wall/r_wall,/area/traitor/tox) "eEg" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; level = 2},/turf/simulated/floor/engine,/area/traitor/tox) "eEh" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 8; frequency = 1443; icon_state = "on"; id = "air_in"; on = 1},/turf/simulated/floor/engine,/area/traitor/tox) @@ -12399,7 +12398,7 @@ "eEw" = (/obj/machinery/light_switch{pixel_x = -24; pixel_y = 0},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/tox) "eEx" = (/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/pipe/simple/visible{dir = 5},/turf/simulated/floor/plating,/area/traitor/atmos) "eEy" = (/obj/machinery/atmospherics/pipe/tank/oxygen{dir = 8; volume = 20000},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/tox) -"eEz" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/grille,/turf/simulated/floor/plating,/area) +"eEz" = (/turf/simulated/wall/r_wall,/area/traitor/rnd) "eEA" = (/mob/living/simple_animal/cat/Syndi,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/hall) "eEB" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/hall) "eEC" = (/obj/machinery/light,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/tox) @@ -12440,9 +12439,9 @@ "eFl" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 4; initialize_directions = 11; level = 2},/turf/simulated/floor/plating,/area/traitor/atmos) "eFm" = (/turf/simulated/floor/plating,/area/traitor/atmos) "eFn" = (/obj/item/weapon/storage/toolbox/electrical{pixel_x = 1; pixel_y = -1},/turf/simulated/floor/plating,/area/traitor/atmos) -"eFo" = (/obj/machinery/door/airlock/glass,/obj/machinery/door/firedoor/multi_tile/triple{layer = 2.6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/hall) -"eFp" = (/obj/machinery/door/airlock/glass,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/hall) -"eFq" = (/obj/machinery/door/airlock/glass,/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/hall) +"eFo" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/rnd) +"eFp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor/plating,/area/traitor/tox) +"eFq" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/tox) "eFr" = (/obj/item/weapon/storage/toolbox/syndicate,/obj/structure/alien/weeds,/turf/simulated/floor/airless{icon_state = "floorgrime"},/area/mine/abandoned) "eFs" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 1},/turf/simulated/floor/plating,/area/traitor/atmos) "eFt" = (/obj/machinery/atmospherics/pipe/manifold/visible,/turf/simulated/floor/plating,/area/traitor/atmos) @@ -12468,7 +12467,7 @@ "eFN" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "dark"},/area/traitor/inter) "eFO" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor{icon_state = "dark"},/area/traitor/inter) "eFP" = (/obj/structure/rack,/obj/machinery/door/window/eastright{base_state = "left"; dir = 8; icon_state = "left"; name = "Fitness Ring"},/turf/simulated/floor{tag = "icon-vault (NORTH)"; icon_state = "vault"; dir = 1},/area/traitor/inter) -"eFQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/plating,/area) +"eFQ" = (/obj/machinery/door/airlock/glass,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/tox) "eFR" = (/obj/structure/rack,/obj/machinery/door/window/eastright{name = "Gear Rack"},/obj/structure/window/reinforced,/turf/simulated/floor{tag = "icon-vault (EAST)"; icon_state = "vault"; dir = 4},/area/traitor/inter) "eFS" = (/obj/structure/table,/obj/item/weapon/reagent_containers/ld50_syringe/choral{pixel_x = 3; pixel_y = 10},/obj/item/weapon/reagent_containers/ld50_syringe/choral{pixel_x = 3; pixel_y = 6},/obj/item/weapon/reagent_containers/ld50_syringe/choral{pixel_x = 3; pixel_y = 2},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/traitor/inter) "eFT" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/traitor/inter) @@ -12495,11 +12494,11 @@ "eGo" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/inter) "eGp" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/inter) "eGq" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/inter) -"eGr" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/multi_tile/glass,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/multi_tile{layer = 2.6},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area) -"eGs" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area) +"eGr" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/space,/area) +"eGs" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/floor/plating,/area/traitor/tox) "eGt" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock{name = "Interrogation"; req_access_txt = "0"},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/inter) -"eGu" = (/obj/machinery/door/airlock/multi_tile/glass,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/multi_tile{layer = 2.6},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area) -"eGv" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area) +"eGu" = (/obj/machinery/door/airlock/glass,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/tox) +"eGv" = (/obj/machinery/door/airlock/multi_tile/glass{dir = 3; name = "Research and Development"; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor/multi_tile{dir = 3; layer = 2.6},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/rnd) "eGw" = (/obj/machinery/chem_dispenser/beer,/obj/structure/table,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/radio) "eGx" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/apc{dir = 1; pixel_y = 24},/obj/structure/table,/obj/machinery/chem_dispenser/soda,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/radio) "eGy" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/light_switch{pixel_y = 24},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/radio) @@ -12526,7 +12525,7 @@ "eGT" = (/obj/machinery/light/small,/turf/simulated/floor{icon_state = "dark"},/area/traitor/inter) "eGU" = (/obj/machinery/optable,/obj/effect/decal/cleanable/blood,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/traitor/surgery) "eGV" = (/obj/structure/table,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/surgery) -"eGW" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/turf/simulated/floor/plating,/area) +"eGW" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/traitor/tox) "eGX" = (/obj/structure/table,/obj/item/weapon/storage/fancy/cigarettes/dromedaryco,/obj/item/weapon/lighter/zippo/fluff/naples_1,/obj/item/ashtray/glass{pixel_y = 7},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/radio) "eGY" = (/obj/structure/table,/obj/item/device/radio/intercom{broadcasting = 1; dir = 8; freerange = 1; listening = 0; name = "Pirate Radio Broadcast Channel"; pixel_x = 0},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/radio) "eGZ" = (/obj/structure/table,/obj/item/weapon/paper/djstation{info = "Welcome new owner!

You have purchased the latest in listening equipment. The telecommunication setup we created is the best in listening to common and private radio fequencies. Here is a step by step guide to start listening in on those saucy radio channels:
  1. Equip yourself with a multi-tool
  2. Use the multitool on each machine, that is the broadcaster, receiver and the relay.
  3. Turn all the machines on, it has already been configured for you to listen on.
Simple as that. Now to listen to the private channels, you'll have to configure the intercoms, located on the front desk. Here is a list of frequencies for you to listen on.
  • 145.7 - Common Channel
  • 144.7 - Private AI Channel
  • 135.9 - Security Channel
  • 135.7 - Engineering Channel
  • 135.5 - Medical Channel
  • 135.3 - Command Channel
  • 135.1 - Science Channel
  • 134.7 - Supply Channel
  • "},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/radio) @@ -12536,7 +12535,7 @@ "eHd" = (/obj/machinery/light/small,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/surgery) "eHe" = (/obj/structure/table,/obj/item/stack/rods,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/surgery) "eHf" = (/obj/structure/table,/obj/item/weapon/hatchet,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/surgery) -"eHg" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/grille,/turf/simulated/floor/plating,/area) +"eHg" = (/obj/machinery/door/firedoor/multi_tile/triple{dir = 3; layer = 2.6},/obj/machinery/door/airlock/glass,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/tox) "eHh" = (/obj/item/clothing/suit/xenos,/obj/item/clothing/head/xenos,/turf/simulated/floor/airless{icon_state = "floorscorched2"},/area/mine/abandoned) "eHi" = (/obj/item/device/radio/beacon,/turf/simulated/floor,/area/mine/production) "eHj" = (/obj/structure/rack,/obj/item/clothing/head/helmet/swat,/turf/simulated/floor,/area/derelict/bridge/access) @@ -12550,6 +12549,483 @@ "eHr" = (/obj/structure/table,/obj/item/weapon/folder/blue,/obj/item/weapon/stamp/hop,/obj/item/device/eftpos,/turf/simulated/floor,/area/crew_quarters/heads) "eHs" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/blue,/obj/machinery/camera{c_tag = "Brig Medbay"; dir = 2; network = list("SS13")},/turf/simulated/floor{icon_state = "white"},/area/security/medbay) "eHt" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/effect/landmark{name = "JoinLateCryo"},/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/sleep) +"eHu" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad2"},/turf/simulated/floor,/area/quartermaster/storage) +"eHv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/conveyor{dir = 4; id = "QMLoad2"},/turf/simulated/floor,/area/quartermaster/storage) +"eHw" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/apmaint) +"eHx" = (/obj/machinery/telecomms/broadcaster/preset_cent,/turf/unsimulated/floor{icon_state = "green"; dir = 6},/area/centcom/control) +"eHy" = (/obj/machinery/door/airlock/centcom{name = "Telecommunications"; opacity = 1; req_access_txt = "106"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) +"eHz" = (/obj/machinery/r_n_d/server/centcom,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) +"eHA" = (/obj/structure/table,/obj/item/weapon/card/id/silver{pixel_x = -3; pixel_y = -3},/obj/item/weapon/card/id/captains_spare,/obj/item/weapon/card/id/fluff/lifetime{pixel_x = 3; pixel_y = 3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) +"eHB" = (/obj/machinery/account_database{name = "Admin Accounts Database"},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) +"eHC" = (/turf/simulated/floor/plating/airless,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "solar_tool_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = -25; req_access_txt = "13"},/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk3"; icon_state = "catwalk3"},/area/solar/auxport) +"eHD" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; level = 2},/turf/space,/area) +"eHE" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; level = 2},/turf/simulated/floor/plating,/area/traitor/tox) +"eHF" = (/obj/machinery/door_control{id = "adminshuttleblast"; name = "blast door control"; pixel_x = -30; req_access_txt = "101"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) +"eHG" = (/obj/machinery/door/poddoor/preopen{id = "adminshuttleblast"; name = "Blast Doors"; req_access_txt = "101"},/obj/machinery/door/airlock/centcom{id_tag = "adminshuttle"; name = "General Access"; opacity = 1; req_access_txt = "101"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) +"eHH" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/traitor/rnd) +"eHI" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/traitor/rnd) +"eHJ" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/rnd) +"eHK" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/rnd) +"eHL" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/tox) +"eHM" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/traitor/hall) +"eHN" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/hall) +"eHO" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/hall) +"eHP" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/traitor/tox) +"eHQ" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/tox) +"eHR" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/traitor/tox) +"eHS" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/hall) +"eHT" = (/turf/simulated/wall/r_wall,/area/traitor/atmos) +"eHU" = (/turf/simulated/wall/r_wall,/area/traitor/inter) +"eHV" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/traitor/hall) +"eHW" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/hall) +"eHX" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/hall) +"eHY" = (/obj/machinery/door/airlock/glass,/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/inter) +"eHZ" = (/obj/machinery/door/airlock/glass,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/inter) +"eIa" = (/obj/machinery/door/airlock/glass,/obj/machinery/door/firedoor/multi_tile/triple{layer = 2.6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/inter) +"eIb" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/plating,/area/traitor/atmos) +"eIc" = (/turf/simulated/wall/r_wall,/area/traitor/radio) +"eId" = (/obj/machinery/door/airlock/multi_tile/glass,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/multi_tile{layer = 2.6},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/surgery) +"eIe" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/radio) +"eIf" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/multi_tile/glass,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/multi_tile{layer = 2.6},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/radio) +"eIg" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/traitor/surgery) +"eIh" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/radio) +"eIi" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/radio) +"eIj" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/radio) +"eIk" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/radio) +"eIl" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/grille,/turf/simulated/floor/plating,/area/traitor/radio) +"eIm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/assembly/assembly_line) +"eIn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/wall/r_wall,/area/engine/chiefs_office) +"eIo" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/turf/simulated/wall/r_wall,/area/engine/chiefs_office) +"eIp" = (/turf/simulated/wall/r_wall,/area/engine/chiefs_office) +"eIq" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/wall/r_wall,/area/atmos) +"eIr" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4; level = 2},/obj/machinery/atmospherics/pipe/simple/visible/cyan{level = 2},/turf/simulated/floor/plating,/area/atmos/distribution) +"eIs" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/portsolar) +"eIt" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/portsolar) +"eIu" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/portsolar) +"eIv" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/maintenance/portsolar) +"eIw" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall/r_wall,/area/engine/engineering) +"eIx" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/engine/hardsuitstorage) +"eIy" = (/turf/simulated/wall/r_wall,/area/engine/hardsuitstorage) +"eIz" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/engine/chiefs_office) +"eIA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/engine/chiefs_office) +"eIB" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/cyan{level = 2},/turf/simulated/floor/plating,/area/atmos/distribution) +"eIC" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/portsolar) +"eID" = (/turf/simulated/wall,/area/atmos/distribution) +"eIE" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/manifold/visible/cyan{dir = 4; initialize_directions = 11; level = 2},/turf/simulated/floor/plating,/area/atmos/distribution) +"eIF" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/portsolar) +"eIG" = (/turf/simulated/wall,/area/maintenance/aft) +"eIH" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/wall/r_wall,/area/atmos) +"eII" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4; level = 2},/obj/machinery/atmospherics/pipe/simple/visible/cyan{level = 2},/turf/simulated/floor/plating,/area/atmos) +"eIJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/atmos) +"eIK" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/cyan{level = 2},/turf/simulated/floor/plating,/area/atmos) +"eIL" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/wall/r_wall,/area/engine/chiefs_office) +"eIM" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/engine/chiefs_office) +"eIN" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall,/area/engine/engineering) +"eIO" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/wall/r_wall,/area/engine/engineering) +"eIP" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/wall/r_wall,/area/engine/engineering) +"eIQ" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"},/turf/simulated/wall/r_wall,/area/engine/engineering) +"eIR" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5; level = 1},/turf/simulated/wall/r_wall,/area/atmos) +"eIS" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/green{dir = 4; level = 2},/obj/machinery/atmospherics/pipe/simple/visible/cyan{level = 2},/turf/simulated/floor/plating,/area/atmos) +"eIT" = (/turf/simulated/wall,/area/engine/engineering) +"eIU" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/wall/r_wall,/area/engine/engineering) +"eIV" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/engine/engineering) +"eIW" = (/turf/simulated/wall/r_wall,/area/atmos) +"eIX" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/cyan{level = 2},/turf/simulated/floor/plating,/area/atmos) +"eIY" = (/turf/simulated/wall/r_wall,/area/storage/secure) +"eIZ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/wall/r_wall,/area/storage/secure) +"eJa" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/engine/engineering) +"eJb" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/atmos) +"eJc" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Singularity"; layer = 2.8; name = "Singularity Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/engine/engineering) +"eJd" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = 0; pixel_y = 0},/turf/simulated/wall/r_wall,/area/engine/engineering) +"eJe" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Singularity"; layer = 2.8; name = "Singularity Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/engine/engineering) +"eJf" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Singularity"; layer = 2.8; name = "Singularity Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/engine/engineering) +"eJg" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Singularity"; layer = 2.8; name = "Singularity Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/engine/engineering) +"eJh" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = 0; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/engine/engineering) +"eJi" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = 0; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/engine/engineering) +"eJj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/engine/engineering) +"eJk" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/engine/engineering) +"eJl" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/turf/simulated/wall/r_wall,/area/engine/engineering) +"eJm" = (/obj/machinery/light/small{dir = 1},/obj/structure/closet/firecloset,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/engine/engineering) +"eJn" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/engine/engineering) +"eJo" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/engine/engineering) +"eJp" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/engine/engineering) +"eJq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/engine/engineering) +"eJr" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/engine/engineering) +"eJs" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/engine/engineering) +"eJt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/engine/engineering) +"eJu" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/engine/engineering) +"eJv" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/engine/engineering) +"eJw" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/engine/engineering) +"eJx" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/engine/engineering) +"eJy" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/engine/engineering) +"eJz" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 9; level = 2},/turf/simulated/floor/plating,/area/atmos) +"eJA" = (/obj/structure/grille,/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering) +"eJB" = (/obj/structure/grille,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering) +"eJC" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/atmos) +"eJD" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/engine/engineering) +"eJE" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/atmos) +"eJF" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/green{dir = 9},/turf/simulated/floor/plating,/area/atmos) +"eJG" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/green{dir = 6},/turf/simulated/floor/plating,/area/atmos) +"eJH" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/plating,/area/atmos) +"eJI" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/yellow{level = 2},/turf/simulated/floor/plating,/area/atmos) +"eJJ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/atmos) +"eJK" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/green{level = 2},/turf/simulated/floor/plating,/area/atmos) +"eJL" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/cyan{level = 2},/turf/simulated/floor/plating,/area/atmos) +"eJM" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "atmos"; name = "Atmos Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/atmos) +"eJN" = (/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering) +"eJO" = (/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering) +"eJP" = (/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering) +"eJQ" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/engine/engineering) +"eJR" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/engine/engineering) +"eJS" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/engine/engineering) +"eJT" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/engine/engineering) +"eJU" = (/obj/machinery/light{dir = 8},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/engine/engineering) +"eJV" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/engine/engineering) +"eJW" = (/obj/structure/sign/securearea,/turf/simulated/wall/r_wall,/area/engine/engineering) +"eJX" = (/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering) +"eJY" = (/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering) +"eJZ" = (/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering) +"eKa" = (/obj/structure/grille,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering) +"eKb" = (/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering) +"eKc" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/assembly/chargebay) +"eKd" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/assembly/robotics) +"eKe" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/toxins/lab) +"eKf" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/bridge/meeting_room) +"eKg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/bridge/meeting_room) +"eKh" = (/turf/simulated/wall/r_wall,/area/crew_quarters/captain/bedroom) +"eKi" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/crew_quarters/captain/bedroom) +"eKj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/medical/chemistry) +"eKk" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/assembly/robotics) +"eKl" = (/turf/simulated/wall/r_wall,/area/hallway/primary/central/sw) +"eKm" = (/turf/simulated/wall,/area/crew_quarters/heads) +"eKn" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/crew_quarters/heads) +"eKo" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/crew_quarters/heads) +"eKp" = (/turf/simulated/wall/r_wall,/area/crew_quarters/heads) +"eKq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/crew_quarters/captain/bedroom) +"eKr" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/crew_quarters/captain) +"eKs" = (/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"},/turf/simulated/wall/r_wall,/area/medical/chemistry) +"eKt" = (/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"},/turf/simulated/wall,/area/medical/exam_room) +"eKu" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/assembly/chargebay) +"eKv" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/assembly/robotics) +"eKw" = (/turf/simulated/wall,/area/crew_quarters/captain/bedroom) +"eKx" = (/turf/simulated/wall,/area/crew_quarters/captain) +"eKy" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/medical/chemistry) +"eKz" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/medical/chemistry) +"eKA" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/medical/chemistry) +"eKB" = (/turf/simulated/wall,/area/medical/chemistry) +"eKC" = (/obj/structure/sign/chemistry,/turf/simulated/wall,/area/medical/chemistry) +"eKD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/medical/morgue) +"eKE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/medical/morgue) +"eKF" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/medical{name = "Morgue"; req_access_txt = "0"; req_one_access_txt = "6,9"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/medical/morgue) +"eKG" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/wall,/area/medical/morgue) +"eKH" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/assembly/robotics) +"eKI" = (/turf/simulated/wall/r_wall,/area/medical/research{name = "Research Division"}) +"eKJ" = (/obj/machinery/status_display,/turf/simulated/wall/r_wall,/area/assembly/robotics) +"eKK" = (/obj/structure/sign/securearea,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/medical/research{name = "Research Division"}) +"eKL" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/medical/chemistry) +"eKM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/medical/medbay3) +"eKN" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbay3) +"eKO" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/turf/simulated/wall,/area/medical/medbay2) +"eKP" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/turf/simulated/wall,/area/medical/medbay2) +"eKQ" = (/turf/simulated/wall/r_wall,/area/medical/medbay2) +"eKR" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/hallway/primary/central/sw) +"eKS" = (/turf/simulated/wall/r_wall,/area/teleporter) +"eKT" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/teleporter) +"eKU" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/medical/medbay3) +"eKV" = (/turf/simulated/wall,/area/toxins/lab) +"eKW" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/toxins/lab) +"eKX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/toxins/lab) +"eKY" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/toxins/lab) +"eKZ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating/airless,/area/medical/research{name = "Research Division"}) +"eLa" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area/medical/research{name = "Research Division"}) +"eLb" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/medical/research{name = "Research Division"}) +"eLc" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/hallway/primary/central/sw) +"eLd" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/wall/r_wall,/area/crew_quarters/heads) +"eLe" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = "0"},/turf/simulated/wall/r_wall,/area/server) +"eLf" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/wall/r_wall,/area/server) +"eLg" = (/turf/simulated/wall/r_wall,/area/server) +"eLh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/teleporter) +"eLi" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/shuttle/plating,/area/medical/research{name = "Research Division"}) +"eLj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/crew_quarters/heads) +"eLk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/server) +"eLl" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/turf/simulated/wall/r_wall,/area/engine/gravitygenerator) +"eLm" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{id_tag = "MedbayFoyer"; name = "Medical Supplies"; req_access_txt = "5"},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/chemistry) +"eLn" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/medical/chemistry) +"eLo" = (/turf/simulated/wall,/area/medical/medbay3) +"eLp" = (/turf/simulated/wall,/area/medical/cryo) +"eLq" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/medical/cryo) +"eLr" = (/turf/simulated/wall,/area/medical/genetics_cloning) +"eLs" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area/medical/genetics_cloning) +"eLt" = (/turf/simulated/wall/r_wall,/area/medical/genetics) +"eLu" = (/turf/simulated/wall,/area/medical/genetics) +"eLv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/assembly/chargebay) +"eLw" = (/turf/simulated/wall,/area/assembly/chargebay) +"eLx" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/assembly/robotics) +"eLy" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/assembly/robotics) +"eLz" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/medical/research{name = "Research Division"}) +"eLA" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/medical/research{name = "Research Division"}) +"eLB" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/medical/research{name = "Research Division"}) +"eLC" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/hallway/primary/central/sw) +"eLD" = (/turf/simulated/wall,/area/engine/gravitygenerator) +"eLE" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/medical/medbay3) +"eLF" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/door/airlock/research{name = "Genetics Research"; req_access_txt = "47;9"},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics) +"eLG" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/crew_quarters/hor) +"eLH" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/plating,/area/crew_quarters/hor) +"eLI" = (/turf/simulated/wall/r_wall,/area/crew_quarters/hor) +"eLJ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/crew_quarters/hor) +"eLK" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/crew_quarters/hor) +"eLL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/medical/research{name = "Research Division"}) +"eLM" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/quartermaster/qm) +"eLN" = (/obj/machinery/status_display/supply_display,/turf/simulated/wall,/area/quartermaster/qm) +"eLO" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/quartermaster/qm) +"eLP" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/quartermaster/qm) +"eLQ" = (/turf/simulated/wall,/area/server) +"eLR" = (/obj/structure/noticeboard,/turf/simulated/wall,/area/medical/medbay3) +"eLS" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{id_tag = "GeneticsDoor"; name = "Genetics"; req_access_txt = "9"},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics) +"eLT" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/obj/machinery/door/airlock/research{name = "Genetics Research"; req_access_txt = "47;9"},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics) +"eLU" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/plating,/area/crew_quarters/hor) +"eLV" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/shuttle/plating,/area/maintenance/asmaint2) +"eLW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/server) +"eLX" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/server) +"eLY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/engine/gravitygenerator) +"eLZ" = (/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"},/turf/simulated/wall,/area/medical/sleeper) +"eMa" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{id_tag = "GeneticsDoor"; name = "Genetics"; req_access_txt = "9"},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics) +"eMb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/toxins/storage) +"eMc" = (/turf/simulated/wall,/area/toxins/storage) +"eMd" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/shuttle/plating,/area/maintenance/asmaint2) +"eMe" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/wall,/area/medical/genetics_cloning) +"eMf" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/crew_quarters/hor) +"eMg" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/disposalpipe/segment,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/cmo) +"eMh" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/cmo) +"eMi" = (/obj/structure/grille,/obj/structure/sign/goldenplaque{desc = "Done No Harm."; name = "Best Doctor 2552"},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/cmo) +"eMj" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/cmo) +"eMk" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/cmo) +"eMl" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/medical/genetics_cloning) +"eMm" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/cable,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/cmo) +"eMn" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/cmo) +"eMo" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/medical/cryo) +"eMp" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/medical/cryo) +"eMq" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/wall,/area/medical/genetics) +"eMr" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/wall,/area/medical/genetics) +"eMs" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/crew_quarters/hor) +"eMt" = (/turf/simulated/wall/r_wall,/area/toxins/mixing) +"eMu" = (/obj/machinery/atmospherics/pipe/simple/insulated,/turf/simulated/wall/r_wall,/area/toxins/mixing) +"eMv" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/poddoor{id = "ToxinsVenting"; name = "Toxins Venting Bay Door"; use_power = 0},/turf/simulated/floor/engine,/area/toxins/mixing) +"eMw" = (/turf/simulated/wall/r_wall{desc = "A specially coated wall that resists temperatures for Science"; max_temperature = 1e+009; name = "Coated Reinforced Wall"},/area/toxins/mixing) +"eMx" = (/obj/structure/sign/directions/engineering,/obj/structure/sign/directions/science{dir = 4; pixel_x = 0; pixel_y = -7},/obj/structure/sign/directions/medical{dir = 4; pixel_y = 7},/turf/simulated/wall,/area/janitor) +"eMy" = (/turf/simulated/wall,/area/janitor) +"eMz" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/janitor) +"eMA" = (/turf/simulated/wall,/area/maintenance/asmaint) +"eMB" = (/turf/simulated/wall,/area/medical/paramedic) +"eMC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/medical/paramedic) +"eMD" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "acutesep"; name = "Acute Separation Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/sleeper) +"eME" = (/obj/structure/sign/greencross,/turf/simulated/wall,/area/medical/sleeper) +"eMF" = (/turf/simulated/wall/r_wall,/area/medical/cmo) +"eMG" = (/turf/simulated/wall,/area/medical/medbreak) +"eMH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/medical/genetics) +"eMI" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction{dir = 4},/turf/simulated/wall/r_wall{desc = "A specially coated wall that resists temperatures for Science"; max_temperature = 1e+009; name = "Coated Reinforced Wall"},/area/toxins/mixing) +"eMJ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area/toxins/test_area) +"eMK" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area/toxins/test_area) +"eML" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/toxins/test_area) +"eMM" = (/turf/simulated/wall,/area/toxins/test_area) +"eMN" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'BOMB RANGE"; name = "BOMB RANGE"},/turf/simulated/wall/r_wall,/area/toxins/test_area) +"eMO" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "Janitor"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "bot"},/area/maintenance/asmaint) +"eMP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/medical/paramedic) +"eMQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/toxins/storage) +"eMR" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/toxins/telescipad) +"eMS" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/toxins/test_area) +"eMT" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/wall,/area/ntrep) +"eMU" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/janitor) +"eMV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/medical/cmo) +"eMW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/medical/medbreak) +"eMX" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/medical/genetics) +"eMY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/wall,/area/medical/genetics) +"eMZ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/wall,/area/medical/genetics) +"eNa" = (/turf/simulated/wall/r_wall,/area/toxins/storage) +"eNb" = (/turf/simulated/wall/r_wall,/area/toxins/telescipad) +"eNc" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/toxins/mixing) +"eNd" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/janitor) +"eNe" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/medical/paramedic) +"eNf" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/disposalpipe/segment,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/cmo) +"eNg" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/cmo) +"eNh" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "staffroom"; name = "Staff Room Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbreak) +"eNi" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'BOMB RANGE"; name = "BOMB RANGE"},/turf/simulated/wall,/area/toxins/test_area) +"eNj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/ntrep) +"eNk" = (/obj/machinery/door/airlock/maintenance{name = "Custodial Maintenance"; req_access_txt = "26"},/turf/simulated/floor/plating,/area/janitor) +"eNl" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock/maintenance{name = "Paramedic Maintenance"; req_access_txt = "66"},/turf/simulated/floor/plating,/area/medical/paramedic) +"eNm" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/wall,/area/medical/medbay2) +"eNn" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/cable,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/disposalpipe/segment,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/cmo) +"eNo" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/cable,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/cmo) +"eNp" = (/turf/simulated/wall,/area/medical/medbay2) +"eNq" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "staffroom"; name = "Staff Room Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbreak) +"eNr" = (/turf/simulated/wall/r_wall,/area/toxins/telesci) +"eNs" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/toxins/telesci) +"eNt" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/toxins/mixing) +"eNu" = (/obj/structure/grille,/obj/structure/window/plasmareinforced{dir = 4},/obj/structure/window/plasmareinforced{dir = 8},/obj/structure/window/plasmareinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area/toxins/mixing) +"eNv" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "scanhide"; name = "Scanning Room Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/sleeper) +"eNw" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/cmo) +"eNx" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/cable,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/disposalpipe/segment,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/cmo) +"eNy" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/wall,/area/medical/cmo) +"eNz" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/cable,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/cmo) +"eNA" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/wall,/area/medical/medbay2) +"eNB" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall,/area/medical/medbreak) +"eNC" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/medical/medbreak) +"eND" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/wall,/area/medical/medbreak) +"eNE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/toxins/mixing) +"eNF" = (/obj/structure/grille,/obj/structure/window/plasmareinforced{dir = 4},/obj/structure/window/plasmareinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area/toxins/mixing) +"eNG" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/maintenance/asmaint) +"eNH" = (/turf/simulated/wall,/area/medical/psych) +"eNI" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "psychoffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/psych) +"eNJ" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area/medical/psych) +"eNK" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "psychoffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/psych) +"eNL" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "psychoffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/psych) +"eNM" = (/obj/structure/grille,/obj/structure/window/plasmareinforced{dir = 4},/obj/structure/window/plasmareinforced{dir = 8},/obj/structure/window/plasmareinforced{explosion_resistance = 10},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area/toxins/mixing) +"eNN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/medical/sleeper) +"eNO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"},/turf/simulated/wall,/area/maintenance/asmaint) +"eNP" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/wall,/area/medical/sleeper) +"eNQ" = (/obj/structure/sign/biohazard,/turf/simulated/wall/r_wall,/area/medical/medbay2) +"eNR" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area/medical/virology) +"eNS" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/wall/r_wall,/area/medical/medbay2) +"eNT" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/medical/biostorage) +"eNU" = (/obj/structure/extinguisher_cabinet,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/wall/r_wall,/area/medical/biostorage) +"eNV" = (/obj/structure/sign/biohazard,/turf/simulated/wall/r_wall,/area/medical/biostorage) +"eNW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"},/turf/simulated/wall,/area/medical/medbay2) +"eNX" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/medical/research{name = "Research Division"}) +"eNY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/storage/tech) +"eNZ" = (/turf/simulated/wall,/area/medical/ward) +"eOa" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/medical/ward) +"eOb" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/medical/ward) +"eOc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/medical/ward) +"eOd" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/wall,/area/medical/ward) +"eOe" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/medical/medbay2) +"eOf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/medical/biostorage) +"eOg" = (/turf/simulated/wall/r_wall,/area/medical/biostorage) +"eOh" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/toxins/telesci) +"eOi" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/wall/r_wall,/area/toxins/telesci) +"eOj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/wall/r_wall,/area/toxins/telesci) +"eOk" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/toxins/xenobiology) +"eOl" = (/turf/simulated/wall/r_wall,/area/toxins/xenobiology) +"eOm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/toxins/xenobiology) +"eOn" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/research{name = "Xenobiology Research"; req_access_txt = "47"},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology) +"eOo" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/medical/ward) +"eOp" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/medical/medbay2) +"eOq" = (/turf/simulated/wall/r_wall,/area/medical/virology) +"eOr" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/shuttle/plating,/area/maintenance/asmaint2) +"eOs" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/toxins/xenobiology/xenoflora_storage) +"eOt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area/toxins/xenobiology/xenoflora_storage) +"eOu" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area/toxins/xenobiology/xenoflora_storage) +"eOv" = (/turf/simulated/wall/r_wall,/area/toxins/xenobiology/xenoflora) +"eOw" = (/turf/simulated/wall,/area/toxins/xenobiology/xenoflora) +"eOx" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor/plating,/area/toxins/xenobiology/xenoflora) +"eOy" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plating,/area/toxins/xenobiology/xenoflora) +"eOz" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area/toxins/xenobiology/xenoflora) +"eOA" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area/toxins/xenobiology/xenoflora) +"eOB" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area/toxins/xenobiology/xenoflora) +"eOC" = (/turf/simulated/wall,/area/engine/controlroom) +"eOD" = (/turf/simulated/wall/r_wall,/area/medical/ward) +"eOE" = (/turf/simulated/wall/r_wall,/area/maintenance/asmaint) +"eOF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/asmaint) +"eOG" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/asmaint) +"eOH" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/asmaint) +"eOI" = (/turf/simulated/wall/r_wall,/area/toxins/xenobiology/xenoflora_storage) +"eOJ" = (/obj/structure/sign/biohazard,/turf/simulated/wall,/area/toxins/xenobiology) +"eOK" = (/obj/structure/sign/securearea,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/toxins/xenobiology) +"eOL" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/wall/r_wall,/area/maintenance/asmaint2) +"eOM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/storage/tech) +"eON" = (/turf/simulated/wall,/area/medical/surgery) +"eOO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/medical/surgery) +"eOP" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "surgeryobs1"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/surgery) +"eOQ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "surgeryobs1"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/surgery) +"eOR" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "surgeryobs1"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/surgery) +"eOS" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "surgeryobs2"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/surgery) +"eOT" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "surgeryobs2"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/surgery) +"eOU" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "surgeryobs2"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/surgery) +"eOV" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/wall,/area/medical/surgery) +"eOW" = (/turf/simulated/wall/r_wall,/area/medical/surgery) +"eOX" = (/turf/simulated/wall/r_wall,/area/solar/starboard) +"eOY" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/solar/starboard) +"eOZ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/cyan{dir = 1; level = 2},/obj/machinery/meter,/turf/simulated/wall/r_wall,/area/engine/controlroom) +"ePa" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/toxins/test_area) +"ePb" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 9; level = 2},/turf/simulated/wall/r_wall,/area/engine/controlroom) +"ePc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/wall/r_wall,/area/medical/medbay2) +"ePd" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/toxins/test_area) +"ePe" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/machinery/meter,/turf/simulated/wall/r_wall,/area/engine/controlroom) +"ePf" = (/obj/structure/sign/biohazard,/turf/simulated/wall/r_wall,/area/toxins/xenobiology) +"ePg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/structure/sign/securearea,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/engine/break_room) +"ePh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/medical/surgery) +"ePi" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/maintenance/asmaint) +"ePj" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/wall/r_wall,/area/medical/virology) +"ePk" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/asmaint) +"ePl" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint) +"ePm" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/solar/starboard) +"ePn" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/solar/starboard) +"ePo" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/solar/starboard) +"ePp" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/wall,/area/medical/surgery) +"ePq" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/medical/surgery) +"ePr" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/medical/virology) +"ePs" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area/toxins/xenobiology/xenoflora) +"ePt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area/toxins/xenobiology/xenoflora) +"ePu" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area/toxins/xenobiology/xenoflora) +"ePv" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/solar/starboard) +"ePw" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/medical/surgery) +"ePx" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "xenobio3"; name = "Containment Blast Doors"; opacity = 0},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/toxins/xenobiology) +"ePy" = (/turf/simulated/wall,/area/toxins/xenobiology) +"ePz" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/toxins/xenobiology) +"ePA" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/solar/starboard) +"ePB" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/medical/surgery) +"ePC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/medical/surgery) +"ePD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/wall/r_wall,/area/medical/surgery) +"ePE" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/turf/simulated/wall/r_wall,/area/medical/surgery) +"ePF" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area/medical/virology) +"ePG" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area/medical/virology) +"ePH" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area/medical/virology) +"ePI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/medical/virology) +"ePJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/wall/r_wall,/area/medical/virology) +"ePK" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/wall/r_wall,/area/medical/virology) +"ePL" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/wall/r_wall,/area/medical/virology) +"ePM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/toxins/xenobiology) +"ePN" = (/turf/simulated/wall,/area/engine/break_room) +"ePO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/wall,/area/medical/virology) +"ePP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/medical/virology) +"ePQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "xenobio3"; name = "Containment Blast Doors"; opacity = 0},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/toxins/xenobiology) +"ePR" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/wall/r_wall,/area/medical/virology) +"ePS" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/medical/virology) +"ePT" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/turf/simulated/wall,/area/engine/break_room) +"ePU" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/medical/virology) +"ePV" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "xenobio2"; name = "Containment Blast Doors"; opacity = 0},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/toxins/xenobiology) +"ePW" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/engine/break_room) +"ePX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area/medical/virology) +"ePZ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area/medical/virology) +"eQa" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/medical/virology/lab) +"eQb" = (/turf/simulated/wall,/area/medical/virology/lab) +"eQc" = (/obj/structure/sign/securearea,/turf/simulated/wall,/area/medical/virology/lab) +"eQd" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "xenobio1"; name = "Containment Blast Doors"; opacity = 0},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/toxins/xenobiology) +"eQe" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/wall/r_wall,/area/medical/virology/lab) +"eQf" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/turf/simulated/wall,/area/medical/virology/lab) +"eQg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/sign/securearea,/turf/simulated/wall,/area/medical/virology/lab) +"eQh" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/medical/virology/lab) +"eQi" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/wall,/area/medical/virology/lab) +"eQj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area/medical/virology/lab) +"eQk" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/medical/virology/lab) +"eQl" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area/toxins/xenobiology) +"eQm" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area/medical/virology/lab) +"eQn" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area/toxins/xenobiology) +"eQo" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/medical/virology/lab) +"eQp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area/medical/virology/lab) +"eQq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area/medical/virology/lab) +"eQr" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area/medical/virology/lab) +"eQs" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area/medical/virology/lab) +"eQt" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/wall/r_wall,/area/medical/virology/lab) +"eQu" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area/medical/virology/lab) +"eQv" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area/medical/virology/lab) +"eQw" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area/medical/virology/lab) +"eQx" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/medical/virology/lab) +"eQy" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/wall/r_wall,/area/medical/virology/lab) +"eQz" = (/turf/simulated/wall/r_wall,/area/medical/virology/lab) +"eQA" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall/r_wall,/area/medical/virology/lab) +"eQB" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area/medical/virology/lab) +"eQC" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area/medical/virology/lab) +"eQD" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area/medical/virology/lab) (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -12597,200 +13073,200 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaiaaiaaiaaiaaiaaiaaiaajaakaalaamaaiaaiaaiaaiaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaanaaoaapaaqaaraasaataaoaaoaaoaauaavaawaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaaxaayaazaaAaaoaaoaataasaaBaaoaauaauaaCaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaanaaoaaDaaEaaFaaoaaGaaHaasaaIaaqaaqaaiaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaaqaaqaaqaaJaaKaaLaataasaaBaaoaaMaaNaaOaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaaPaaQaaRaaSaaTaaUaaVaaWaaXaaoaaYaaZaaZaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiabaabbabcabdabeabfabgabhaataaBaaqaaqabiaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiabjaaiabkablabmabmaaiaaiabnaalaaiaaiaboaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiabpaaqabqabrabsabtaaaaaaaaaaaaaaaaaiabuaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiabpaaqabqabvaaiaaaaaaaaaaaaaaaaaaaaiaaiaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaiaaiaaiaaiabwaaqabxabyaaiaaiaaiaaiaaaaaaaaaabzabAabAabzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiabCabDabEabFabGabHabIabJabKabLaaiaaaaaaaaaaaaabzabAabMabzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaafaafaafaafaafaaaaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiabNabOabPabQabRabSabTabUabVabVaaiaaaaaaaaaaaaaaaabzabAabAabzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaafaafaafaafaafaaaaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWaaaaaaaaaabWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaaiaaiaaiaaiaaiabXabYabZacaacbaaiaccaaaaaaaaaaaaaaaabzabAabAabzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiacdaceacfacgachaciabTaaiaaiaaiaaiaaaaaaaaaaaaaaaaaaaaaabzabAabAabzaaiaaiaaiacjackaaiaaiaaiabzabzabzabzabzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWaaaaaaabWaaaaaaabWabWabWabWabWabWabWaaaaaaabWaaaaaaabWaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaclacmacnacoacpacqacraaiacsaaiaaiaaiaaiaaiaaaaaaaaaaaaaaaabzactacuaaiacvacwacxacyaczacAaaiabAabAabAabAabAabzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWaaaabWabWabWabWabWabWabWabWabWaaaabWabWabWabWaaaaabaabaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiacBacCacDacEacFacGacraaiaaiaaiacHacIacJaaiaaiaaiaaaaaaaaaaaaabzacuaaiacKacLacMacLacLacNaaiaaiaaiaaiaaiaaiaaiabAacOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaaaaahaahaahaahaahaaaaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWaaaabWabWabWabWabWabWabWabWabWaaaabWabWabWabWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaaiaaiaaiaaiaaiacPacQaaiaaiacRacSacTacUacVaaiaaiaaaaaaaaaaaaaaaabzaaiacWacXacYacZadaadbaaiadcaddadeadfadgadhadiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaaaaahaahaahaahaahaaaaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWaaaabWabWabWabWabWabWabWabWabWaaaabWabWabWabWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiadjadkadladmaaiadnadoaaiadpadqadradsadtaduadvaaiaaaaaaaaaaaaaaaaaaaaiadwadxadyadzacLadAaaiadBadgadgadgadgadhadiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaaiaaiaaiaaiadCadDadEadFaaiabXabTaaiadGadHadIadsadJadKadLaaiaaaaaaaaaaaaaaaadMaaiadNadOadPadQadRadSaaiadTadgadUadgadgadhadiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiadVadWadXaaiadYadZaeaaeaacFaebacraaiaecadHadIaedadJadKaeeaaiaaaaaaaaaaaaaaaaaaaaiaefadxaegadzacLaehaaiaeiadgadgadgadgaejadiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWaaaaaaaaaaaaaaaaaaaaiaaiaaiaaiaaiaaiaaiaaiaaiaaaaaiaekaelaemaenaeoaepaeoaeqacFacGacraaiaaiaeraesaetaeuaevaaiaaiaaaaaaaaaaaaaaaaaaaaiaewaexaeyacLaezaeAaaiaeBaeCaeDaeDaeEaaiabAabMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWaaaaaaaaaaaaaaaaaaaaiaeFaeGaeHaaiaeIaeGaeJaaiaaaaaiaeKaeLaeMaaiaaiaeNaaiaaiaaiaeOaePaaiaaiaeQaeRaeSaeTaeUaaiaaiaaiaaiaaiaaiaaiaaiaaiaeVaeWaeXaeYaeZaaiaaiafaafbafcafdafeaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWaaaaaaaaaaaaaaaaaiaffafgafhaaiaffafgafhaaiaaaaaiafiafjafkachaflafmafnafoafpafqafrafsaaiaaiaftafuafvaaiaaiaaiafwafxafyafyafzafAafBafCafDafEafyafyafFafGafHafIafJafKafLaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWaaaaaaaaaaaaaaaaaiafMafhafNaaiafOafhafPaaiaaaaaiaaiaaiaaiaaiafQafRafSafTafUafVafWafXaaqafYafZagaagbagcagdaaqageagfaggaggaggaghagiagjagkaggaggaggaggaglafcagmagnagoagpagqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWaaaaaaabWabWabWabWabWabWabWaaaaaaabWabWabWabWaaaaaaaaaaaaaaaaaaaaiafhaffafhaaiafhaffafhaaiaaaaaiagsagtagtaguagvagwagxagyagzagAagBagCaaqagDagEagFagGagHagHagIagJagKagLagLagLagMagNagOagPagQagLagLagRagSabZagTagUagVagWaaiaaiaaiaaiaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWabWabWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaffafhaffaaiaffafhaffaaiaaaaaiagXagYagZacFahaahbahcahdaheahfahgahhaaqahiahjahkahlahmahnaaqaaJahoahpahqahraaqahsahtahuahvahqahraaqaaqaaiaaiaaiaaiaaiaaiahwahwahwaaiaaaaaaahxahxahxahxahxaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWabWabWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaffaffafhaaiaffaffafhaaiaaaaaiahyahzahAaaiafQahBahCabJahDahEahFahGaaqahHahIagFahJahKahLaaqahMahNahOahPahQahRahSahTahUahVahWahXahWahYaaiahwahwahwahwahwahwahwahwaaiaaaaaaahxahxahxahxahxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWabWabWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiafhaffahZaaiafhaffaiaaaiaaiaaiaibaicaidaaiaaqaaqaaqaaqaieaifaigaihaaqaiiaijaikailaimainaaqaioaipaiqairaisaitaiuaivahUahVaiwahXaiwaixaaiahwahwahwahwahwahwahwahwaaiaaaaaaahxahxahxahxahxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWabWabWaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaiaiyaizaiAaiBaiyaizaiAaiCaaiaaqaaqaaqaaJaaqaaqaaqaaqaiDaiEaiFaiGaiHaaiaiIaiJaiKaiLaiMaaqaaqaiNaiOaPFaiQaisaiRaiQaivaiSahVahTahTaiTaiUaiVahwahwahwahwahwahwahwahwaaiaaaaaaahxahxahxahxahxaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWabWabWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaiWaiXaiYaffaiZajaajbajcaaiajdajeeHsajgajfajfajfaaqajhajiajjajkajlajmajnajoajpajqajrajsajtajuaiPaiPaiQajvajwajxajyajzajAajBajCajDahTajEahwahwahwahwahwahwahwahwaaiaaaaaaahxahxahxahxahxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajFaaaaaaaaaajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiajGaffajHajIajJajKajLajMaaiajNajOajPajQajRajSajTaaqajUajVajWajXajlajYajZakaakbakcakdakeakfakgaiPakhakiakjakkaklakmaknakoahTahTahTakpaiVahwahwahwahwahwahwahwahwaaiaaaaaaahxahxahxahxahxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakqakqakqacuacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiakraksajHaffaktajKakuakvaaiakwakxakyakzakAakBajTaaqakCakDakEakFakGajmakHakIajpakJakKajsakLakMakNakNakOaisakPakQakRakSahTahWahXahTakTaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaaaaaahxahxahxahxahxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakqaaaaabaaaakUaaaaaaaaaaaaaaaaaaaabaaaajFaaaaaaajFaaaaaaajFajFajFajFajFajFajFaaaaaaajFaaaaaaajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuakVakWakWakWakXakYaaaaaaaaiaaiaaiaaiaaqaaqakZalaalbaaqaaqalcaldalealfalgalhaliaaqaljalkallajXalmaaqalnaloalpalqalraaqalsaltalualvalwalxalyalzalAalBahTaiwalCalDalEaaiaaiaaiaaiaaiaaiaaaaaaaaaaaaaaaaaaahxahxahxahxahxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakqaabalFaabakqaaaaaaaaaaaaaaaaaaaaaaaaajFajFajFajFaaaajFajFajFajFajFajFajFajFajFaaaajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacualGalHalIalJalGalKalLalLalMalNalOalPalQalRalSalTalUalVaaqaaqalWalXaaqaaqaaqaaqaaqalYalZamaambalYaaqaiIaiJamcaiLaiMaaqamdamealYamfaaqaaqaaqaaqamfamgamhalYaaqaaiamiaaiamjamkamlamlammaaaaaaaaaaaaaaaaaaahxahxahxahxahxaaaaaaaaaaaaaaaaaaakqakqakqakqakqaaaaaaaaaamnaaaaaaaaaakqakqacuacuacuaaaaaaajFajFajFajFaaaajFajFajFajFajFajFajFajFajFaaaajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaamaamaamaamaamaamaamaajaakaalaaEaamaamaamaamaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaanaaoaapaaJaaraasaataaoaaoaaoaauaavaawaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaxaayaazaaAaaoaaoaataasaaBaaoaauaauaaCaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaanaaoaaDabmaaFaaoaaGaaHaasaaIaaJaaJaamaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaJaaJaaJabsaaKaaLaataasaaBaaoaaMaaNaaOaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaPaaQaaRaaSaaTaaUaaVaaWaaXaaoaaYaaZaaZaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamabaabbabcabdabeabfabgabhaataaBaaJaaJabiaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaamabjaamabkablabtabtaamaamabnaalaamaamaboaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamabpaaJabqabrabJabZaaaaaaaaaaaaaaaaamabuaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamabpaaJabqabvaamaaaaaaaaaaaaaaaaaaaamaamaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaamaamaamaamabwaaJabxabyaamaamaamaamaaaaaaaaaabzabAabAabzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamabCabDabEabFabGabHabIaccabKabLaamaaaaaaaaaaaaabzabAabMabzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaafaafaafaafaafaaaaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamabNabOabPabQabRabSabTabUabVabVaamaaaaaaaaaaaaaaaabzabAabAabzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaafaafaafaafaafaaaaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWaaaaaaaaaabWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaachachachachachachabXabYacsacaacbaamadMaaaaaaaaaaaaaaaabzabAabAabzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaachacdaceacfacgafaaciabTaamaamaamaamaaaaaaaaaaaaaaaaaaaaaabzabAabAabzafHafHafHacjackafHafHafHabzabzabzabzabzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWaaaaaaabWaaaaaaabWabWabWabWabWabWabWaaaaaaabWaaaaaaabWaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaachaclacmacnacoacpacqacraamaiVagqagqagqagqagqaaaaaaaaaaaaaaaabzactacuafHacvacwacxacyaczacAafHabAabAabAabAabAabzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWaaaabWabWabWabWabWabWabWabWabWaaaabWabWabWabWaaaaabaabaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaachacBacCacDacEalYacGacraamagqagqacHacIacJagqagqagqaaaaaaaaaaaaabzacuafHacKacLacMacLacLacNafHamdamdamdamdamdamdabAacOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaaaaahaahaahaahaahaaaaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWaaaabWabWabWabWabWabWabWabWabWaaaabWabWabWabWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaachachachachachachacPacQagqagqacRacSacTacUacVagqagqaaaaaaaaaaaaaaaabzafHacWacXacYacZadaadbafHadcaddadeadfadgadhadiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaaaaahaahaahaahaahaaaaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWaaaabWabWabWabWabWabWabWabWabWaaaabWabWabWabWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamfadjadkadladmamfadnadoagqadpadqadradsadtaduadvagqaaaaaaaaaaaaaaaaaaafHadwadxadyadzacLadAafHadBadgadgadgadgadhadiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamiamiamiamiamiadCadDadEadFamfabXabTagqadGadHadIadsadJadKadLagqaaaaaaaaaaaaaaaaoaafHadNadOadPadQadRadSafHadTadgadUadgadgadhadiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamiadVadWadXamiadYadZaeaaeaaomaebacragqaecadHadIaedadJadKaeeagqaaaaaaaaaaaaaaaaaaafHaefadxaegadzacLaehafHaeiadgadgadgadgaejadiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWaaaaaaaaaaaaaaaaaaaosaosaosaosaosaosaosaosaosaaaamiaekaelaemaenaeoaepaeoaeqaomacGacragqagqaeraesaetaeuaevagqagqaaaaaaaaaaaaaaaaaaafHaewaexaeyacLaezaeAafHaeBaeCaeDaeDaeEamdabAabMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWaaaaaaaaaaaaaaaaaaaosaeFaeGaeHaosaeIaeGaeJaosaaaamiaeKaeLaeMamiamfaeNamfamfamfaeOaePaamagqaeQaeRaeSaeTaeUagqaoxaoxaoxaoxaoxaoxaoxafHaeVaeWaeXaeYaeZafHafHaoyafbafcafdafeamdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWaaaaaaaaaaaaaaaaosaffafgafhaosaffafgafhaosaaaamiafiafjafkaoHaflafmafnafoafpafqafrafsagqagqaftafuafvagqagqaoxafwafxafyafyafzafAafBafCafDafEafyafyafFafGaoIafIafJafKafLamdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWabWaaaaaaaaaaaaaaaaosafMafhafNaosafOafhafPaosaaaamiamiamiamiamiafQafRafSafTafUafVafWafXaoJafYafZagaagbagcagdapuageagfaggaggaggaghagiagjagkaggaggaggaggaglafcagmagnagoagpapvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWaaaaaaabWabWabWabWabWabWabWaaaaaaabWabWabWabWaaaaaaaaaaaaaaaaaaaosafhaffafhaosafhaffafhaosaaaapwagsagtagtaguagvagwagxagyagzagAagBagCaoJagDagEagFagGagHagHagIagJagKagLagLagLagMagNagOagPagQagLagLagRagSapxagTagUagVagWamdapKapKapKapKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWabWabWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaosaffafhaffaosaffafhaffaosaaaapwagXagYagZaqsahaahbahcahdaheahfahgahhaoJahiahjahkahlahmahnaqtaquahoahpahqahraqtahsahtahuahvahqahraqtaqtapKamdamdamdamdamdahwahwahwapKaaaaaaahxahxahxahxahxaaaaaaaaaabBabBabBabBabBabBabBabBabBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWabWabWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaosaffaffafhaosaffaffafhaosaaaapwahyahzahAapwafQahBahCaqvahDahEahFahGaoJahHahIagFahJahKahLaqtahMahNahOahPahQahRahSahTahUahVahWahXahWahYapKahwahwahwahwahwahwahwahwapKaaaaaaahxahxahxahxahxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWabWabWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaosafhaffahZaosafhaffaiaaosaaaapwaibaicaidapwaqyaqyaqyaqyaieaifaigaihaoJaiiaijaikailaimainaqtaioaipaiqairaisaitaiuaivahUahVaiwahXaiwaixapKahwahwahwahwahwahwahwahwapKaaaaaaahxahxahxahxahxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWabWabWaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaosaiyaizaiAaiBaiyaizaiAaiCarkarjarjarjarlarjarjarjarjaiDaiEaiFaiGaiHarSaiIaiJaiKaiLaiMarTaqtaiNaiOaPFaiQaisaiRaiQaivaiSahVahTahTaiTaiUarUahwahwahwahwahwahwahwahwapKaaaaaaahxahxahxahxahxaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWabWabWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaosaiWaiXaiYaffaiZajaajbajcarkajdajeeHsajgajfajfajfarjajhajiajjajkajlajmajnajoajpajqajrajsajtajuaiPaiPaiQajvajwajxajyajzajAajBajCajDahTajEahwahwahwahwahwahwahwahwapKaaaaaaahxahxahxahxahxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajFaaaaaaaaaajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWabWabWabWabWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaosajGaffajHajIajJajKajLajMarkajNajOajPajQajRajSajTarjajUajVajWajXajlajYajZakaakbakcakdakeakfakgaiPakhakiakjakkaklakmaknakoahTahTahTakparUahwahwahwahwahwahwahwahwapKaaaaaaahxahxahxahxahxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakqakqakqacuacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaosakraksajHaffaktajKakuakvarkakwakxakyakzakAakBajTarjakCakDakEakFakGajmakHakIajpakJakKajsakLakMakNakNakOaisakPakQakRakSahTahWahXahTakTapKapKapKapKapKapKapKapKapKapKaaaaaaahxahxahxahxahxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakqaaaaabaaaakUaaaaaaaaaaaaaaaaaaaabaaaajFaaaaaaajFaaaaaaajFajFajFajFajFajFajFaaaaaaajFaaaaaaajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuakVakWakWakWakXakYaaaaaaaaaaosaosaosarVarVakZalaalbarVarjalcaldalealfalgalhaliarjaljalkallajXalmarTalnaloalpalqalrarTalsaltalualvalwalxalyalzalAalBahTaiwalCalDalEapKasnasnasnasnasnaaaaaaaaaaaaaaaaaaahxahxahxahxahxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakqaabalFaabakqaaaaaaaaaaaaaaaaaaaaaaaaajFajFajFajFaaaajFajFajFajFajFajFajFajFajFaaaajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacualGalHalIalJalGalKalLalLalMalNalOalPalQalRalSalTalUalVarjarjalWalXarjarjarjarjarjatpalZamaambatparTaiIaiJamcaiLaiMarTatEameaugauiaqtaqtaqtaqtauiamgamhaugaqtapKaujapKamjamkamlamlammaaaaaaaaaaaaaaaaaaahxahxahxahxahxaaaaaaaaaaaaaaaaaaakqakqakqakqakqaaaaaaaaaamnaaaaaaaaaakqakqacuacuacuaaaaaaajFajFajFajFaaaajFajFajFajFajFajFajFajFajFaaaajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaacuacuakqacuacuaaaaaaaaaaaaaaaaaaaaaaaaakqamoampamqamramsamtamuamvamwamxamyamzamAamBamCamDamEamFamGamHamIamJamKamLamKamKamMamNamOamPamQamKamRamSamTamUamVamWamXamYamZamKanaanbancandaneanfanganhanianjankanlanmannanoanpanqanraaaaaaaaaaaaaaaaaaahxahxahxahxahxaaaaaaaaaaaaaaaaaaakUaaaaaaaabaabaabaaaaaaamnaabaabaaaaabaabaaaaaaacuaaaaaaajFajFajFajFaaaajFajFajFajFajFajFajFajFajFaaaajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaaaaabaaaakUaaaaaaaaaaaaaaaaaaaaaaaaakqalGansantanualGalKanvanwanxanyanzanAanBanCanDanDanEanFanGanHanIanJanKanLanManNanOanPanNanQanRanKanSanTanUanKanKanUanOanTanUanKanKanSanTanManVanWanXanYanZaoaaobaocaaqannaodamlamlaoeaaaaofaogaofaaaaaaaaaahxahxahxaaaaaaaaaaaaaaaaaaaaaakqaabaohaohaohaohaohaabaoiaabaohaohaohaohaohaabakqaaaaaaajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakqaabaojaabakqaaaaaaaaaaaaaaaaaaaaaaaaakqalGaokaokaolalGaaaaaaaaaaomaaiaonaooaopaaqaaqaaqaaqaaqaaqaaqaoqaoraaqaaqaaqaosaotaouaosaaqaaqaaqaovaowaaqaoxaoyaaqaozaowaaqaaqaaqaoAaoBaaqaaJaoCaoDaoEaoFaaqamfaocaoGaaiaaiaaiaoHaoIaoJaaiaoKaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakqaabaoLaoMaoMaoMaoMaoNaoOaoPaoQaoQaoQaoQaoRaabakqaaaaaaajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaacuacuacuakqakqaaaaaaaaaaoSaaaaaaaaaakqakqacuacuacuaaaaaaakUamoaoTaokaoUalGalKaoVanwaoWaoXaoYaoZapaapbapcapdaaqapeapfapgaphapiapjapkaplapmapnapoappapqaprapjapsaptapuapvapwapxapyaptaaqapzapAapBapCaaqapDapEapFapGapHapIamfaocapJapKapLapMapNapNapOaaiapPaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakqaabapQapQapQapQapQaabapRaabapQapQapQapQapQaabakqaaaaaaajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaacuaaaaaaaabaabaaaaaaaaaaoSaabaabaaaaabaabaaaaaaacuaaaaaaakqalGapSaokaokapTapUapVapWapXapYamDapZaqaamyamyaqbaaqaqcaqdaqeaqfaqgaqhaqiaqjaqkaqlaqmaqnaqjaqoaqpaqqaqraqsaqtaquaqvaqwaqxaqyaqzaqAaqBaqCaaqaqDaqEaqEaqFaqEaqGamfaocannannannannaqHannaqIaqJaqKaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaaaaaaaaaaabaaaaaaaabapRaaaaaaaaaaabaaaaaaaaaacuaaaaaaajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaacuaabaqLaqLaqLaqLaqLaabaqMaabaqLaqLaqLaqLaqLaabacuaaaaaaakqalGaqNaqNaqNalGalKalLalLaqOaqPaqQanDaqRaqSamyaqTaaqaqUaqVaqWaqXaqYaqZaraarbarcardarearfargarhaqZariaqxarjarkarlarjaqwaqxaaqarmarnaroarpaaqarqarraqEaqFaqEarsamfartaruarvarwarvarxaryaaiaaiaaqaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakqaabaohaohaohaohaohaabapRaabaohaohaohaohaohaabakqaaaajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaacuaabarzarAarAarAarAarBarCarDarEarEarEarEarFaabacuaaaaaaakqarGarHarHarHarIarJaaaaaaaaiaaiaaiaaiaaiarKamyarLaaiaaqaaqaaqarMarNaaqaaqaaqaaqarOarPaaqaaqaaqaaiarQarRarSarTarUarVaqwarWaaqarXarYarZasaabJasbascasdaseaqEasfamfasgashasiasjaskaslasmasnasoaspaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakqaabaoLaoMaoMaoMaoMaoNaoOaoPaoQaoQaoQaoQaoRaabakqaaaajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaabasqasqasqasqasqaabasraabasqasqasqasqasqaabacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiassamyarLaaiastapfapgaphapiapjasuaplasvaswasxasyaszasAapjasBasCasDasEasFasFasGasHaaqasIasJasKasLaaqasMasNasOaqFaqEasPamfasgaqHashashashasQannasRasSasTaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakqaabapQapQapQapQapQaabapRaabapQapQapQapQapQaabakqaaaaaaajFajFajFajFaaaaaaajFajFajFajFajFajFajFaaaaaaajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaaaaaaaaaaabaaaaaaaabasraaaaaaaaaaabaaaaaaaaaacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiasUamyasVaaiaqcasWasXasYasZataatbatcatdateatfatgathatiatjatkatlatlatmatlatlatnatoatpatqatratsattaaqatuatvatwatxatyatzamfasgatAatBatBatBatCatDatEatFatGaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatHaaaaaaaaaaabaaaaaaaaaapRaaaaaaaaaaabaaaaaaaaaacuaaaaaaaaaaaaaaaaaaaaaaaaajFajFajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaabaqLaqLaqLaqLaqLaabasraabaqLaqLaqLaqLaqLaabacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiatIamyatJaaiaqUatKatLatMatNaqZaraatOatPatQatRatPatSarhaqZatTatUatVatUatUatVatUatWaaqarXatXatsatYaaqatZauaaubaucaudaudaueaufaugaaqaaqaaqaaJaaqabmaaiaaiaaiaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaakqaabaohaohaohaohaohaabapRaabaohaohaohaohaohaabakqaaaaaaaaaaaaaaaaaaaaaaaaajFajFajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaabarzarAarAarAarAarBarCarDarEarEarEarEarFaabacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaaiaaiaaiaaiaaiaaiaaiauhaaiaaiaaiaaiauiacFaujacFacFaujacFaujacFacFabtaaiaaiaukaulaumaunaulaumaunauoaaiaaiaaiaaiaaiaaqaupauqauraurausaurautauuaaqauvauwauxaaJauyauzauAauBaaqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaabaoLaoMaoMaoMaoMaoNaoOaoPaoQaoQaoQaoQaoRaabakqaaaaaaaaaaaaaaaaaaaaaaaaajFajFajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaabasqasqasqasqasqaabasraabasqasqasqasqasqaabacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqauCauDauEauFauGauHauIauJauIauKauIauIauLauMauMauMauMauMauNauOauPauMauMauMauMauQauMauMauMauMauRauSauTauUauVauWauXauYaaqauZavaavbavcavdaveavfavgaaqavhaviavjaaJavkavlavkavmaaqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaaaapQapQapQapQapQaabapRaabapQapQapQapQapQaaaakUaaaaaaaaaaaaaaaaaaaaaaaaajFajFajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatHaaaaaaaaaaabaaaaaaaaaasraaaaaaaaaaabaaaaaaaabacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqavnavoavpavqavqavravsavtavuauRauRauRavvauRauRauRauRauRavwauRauRauRauRauRauRavxauRauRauRauRavyauRavzauRavAauRauRavBaaqavCavDavEavFavbavGavfavHaaqavIavJavKavLavMavNavOauBaaqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaaaaabaaaaaaaaaaaaaabapRaaaaaaaaaaaaaaaaabaaaakqaaaaaaaaaaaaaaaaaaaaaaaaajFajFajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaabaqLaqLaqLaqLaqLaabasraabaqLaqLaqLaqLaqLaabacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqavPavQavRavSavTaaqavUavVavWavXavYavZawaawbavVavXavXavXawcavXavXavXavXavXavXawdaweawfawfawfawgawhawiawhawjawkawhawlaaqaaiaaiaaiaaiaaiaaiavfavgaaqawmaviawnaaJavkawoavkavmaaqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuacuakqaaaaaaaaaaabaabapRaabaaaaaaaaaaaaakqakqakqaaaaaaaaaaaaaaaaaaaaaaaaaaaajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaofawpaofaaaaaaaaaaaaaaaaaaaaaacuaabarzarAarAarAarAarBarCarDarEarEarEarEarFaaaacuaaaaaaaaaaaaaabaaaaaaaaaaaaaaqaaqaaqaaqaaqaaqaaqaaqaaqaosawqawrawsaaJawtaaqawuawvaaqawwaaqaaqaaqaaqaaqaaqaaqawxaaqaaqawyawzawAamfaaqaosaaqawBaaqaaqapMannannannannannawCavgaaqawDaviawEaaJawFavNavOauBaaqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabawHawIawHaaaaaaaaaaaaaaaaaaaaaacuaabasqasqasqasqasqaabawJaabasqasqasqasqasqaabacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaosawKawLawMaaJawNaaqawOawPawQawRawSawTawUawVawWawXawYawZaxaaxbaxcauRauSaxdaxeaxfaxgaxgaxgaxgaxgaxhaxgaxgaxgaxgaxiaxjaxkaxlaxmaxnaxoaxpaxqavkavmaaqaaaaaaaaaaaaaaaaaaaabaxraxsaxsaxsaxsaxsaxtaabaaaaaaaaaaaaaaaaaaaxuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxvaxwaxxaaaaxyaxzaxAaaaaabaxBaxCaxBaaaaaaaaaaaaaaaaaaaaaacuaaaaabaabaabaabaabaaaaxDaaaaaaaaaaaaaaaaaaaabacuaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxEaxFaxGaxHaaJawNaaqaxIaxJaxKawRaxLaxMaxNaxNaxNaxNaxNawZaxNaxOauMauRauSaaqaxPaxQabJabJabJabJaxRaxQabJabJabJabJabJabJaxSabJaxTaxUaxVabJaxWaxXaaqaaqaaqaaqaaqaaqaaqaaqaaqaxYaxZaxZaxZaxZaxZaxYaaiaaaaaaaaaaaaaaaaaaaxuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayaaybaycaybayaaydayeaydayaaabaxBayfaygaaaaaaaaaaaaaaaaaaaaaacuacuacuacuaaaaaaaaaaaaaxDaaaaaaaaaaaaaaaaaaaaaacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaabaabaabaaqayhayiaxHaaJawNaaqayjaykaylawRaymaxNaxNaynaxNayoayoawZaxNaxOauMauRaypaaqayqaxQayraysaytaaqayuayvaywayxayyayzayAayBayCayDayEayFayGayHayIayJayKayLayMayNayOayPayQayRaaqaxYaxZaxZaxZaxZaxZaxYaaiaabaaaaaaaaaaaaaaaaxuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaySaybayTaybaySaydayUaydaySayVayWayXayYayZayZazaayVayVaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaxDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazbazbazbazbazbazbazbazbazbaabaaqazcazdazeaxVazfabJazgazhaziazjawSazkaxNazlazmaznazoazpazqaxOauMauRauSaaqasgazrazsaysaytaaqaztayRayRayRayRayRayRayRayRayRayRazuazvazwazxazyazzazAazBazBazBazBazCazBazDazEaxZaxZaxZaxZaxZazEaaiaaiaaiaaaaaaaaaaaaaxuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaySazFazGazHaySazIazJazKaySaxCaxCazLazMazNazOazPazQayVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazRazSazTazUazVazWazXazYazbaabaaqazZaAaaAbaaqaAcaaqaAdaAeaAfaAgaAhaznaAiaAjaAkaAlaAmaAnaAoaApaAqavtaArabZaAsaAtaAuaysaytaaqaAvayRayRaAwaAwaAwayRayRayRayRaAxaAyaAzaAAaABaACaADaAEaAFaAGaAFaAFaAHaAFaAIaAJaxZaxZaxZaxZaxZaAKaALaAMaANaaaaaaaaaaaaaxuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaySaAOaAPaAQaySaAOaAPaAQaySaARaASaASaxCaxCaxCaASaASawHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxDaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaabaabaaaaaaaabaATazSaAUaAVaAWaAXaAYaAYazbaaqaaqaxEabZabZabZaAZabZaBaabZabZabZaBbabZabZaaEabZabZabZabZabsaugaBcauRaBdaaqasgaosaHvaysaytaaqaztayRaAwaBfaBfaBgaAwayRaBhayRaBiaBjaBkaBlaBmaBnaBoaBpaBnaBqaBnaBnaBraBhaBsaANaxZaxZaxZaxZaxZaANaBtaBuaBvaaaaaaaaaaaaaxuaaaaaaaaaaaaaaaaaaaaaaaqaaqaBwaBxaBxaBxaBxaByaaqaaqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayaaySaBzaBAayaaySaBBaBAayaaySaBCaySaySaySaySaySaASaxBaaaaaaaaaaaaaaaaaaaaaaabaaaaBDaBEaBDaabaabaabaabaaaaaaaaaaabazbazbazbazbaBFaBGaBGaBHazbazbazbazbaBIaAYaAYazbaBJaBKaBLaBMaBMaBNaBOaBPaBQaBQaBQaBQaBRaBQaBSaBTaBUaBQaBQaBVaBVaBWaBXaBYaBZabJaCaaosaCbaBeaBeaaqaztayRaAwaCcaCdaCeaAwayRayRaCfaCgaBjaChaCiayRayRaCjaCkayRaClayRayRaCmayRaCnaCoaxZaxZaxZaxZaxZaCoaCpaBuaBvaaaaaaaaaaaaaCqaaaaaaaaaaaaaaaaaaaaqaaqaCraCsaCtaCuaCvaCwaCxaCtaaqaaqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCyaCzaCAaCzaCBaCzaCCaCzaCDaCEaCFaCFaCFaCFaCGaySaCHaxBaaaaabaabaaaaaaaaaaaaaabaaaaCIaCJaCKaabaaaaabaaaaaaaaaaaaaaaazbaCLaCMaCNaCMaCMaCMaCMaCOaCMaCMaCPaCQaCNaCRaCSaCSaCSaCSaCSaCSaCSaCTaaiaaiaaiaaiaiVabmaaiaCUaaiafaaiVaaiaaiaaiaaiaCVaCWaCXaCYaCZaAtaDaaDbaBeaDcaztayRaAwaDdaBfaBfaAwayRayRayRaDeaDfaDgaDhayRayRaCjaDiayRayRayRayRaDjayRaDkaDlaxZaxZaxZaxZaxZaDmaDnaDoaCoaaaaaaaaaaDpaDqaDpaaaaaaaaaaaqaaqaaqaDraCuaDsaCuaDtaDuaCuaCuaCuaDvaaqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDwaDxaDyaDzaDAaDBaDCaDDaDEaDCaDFaDGaDCaDCaDHaySaxCayWaabaabaaaaaaaaaaaaaaaaabaDIaDJaDKaDLaDMaaaaabaaaaaaaaaaaaaaaazbaDNazbaDOaDPaDQaDQaDQaDRaDQaDQaDQaDSaDOaDTaDUaDUaDUaDUaDUaDUaDUaAYaaiaDVaDWaDXaDYaDZaEaaEbaEcaEdaEeaEfaDWaEgaaiaEhauRaEiaaqaEjaosaEkaElaElaEmaEnaEoaEpaEqaEqaEraEsaBnaEtaEsaEsaEuaEvaEwayRayRaExaEyaEzaEAaEAaEAaEBayRaECaEDaxZaxZaxZaxZaxZaEEaaiaaiaaiaaaaaaaaaaEFaEGaEFaaaaaaaaqaaqaEHaaqaEIaEJaEKaELaCuaCuaEMaENaCuaEOaaqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaySaEPaEQaEPaERaDyaDyaESaEPaEQaEPaETaEUaEVaEWaySaxCayVayVaEXayZayZayZayZazaayVaEYaEZaFaaFbaEYazbazbaFcaFdaFeazbazbazbaDNaFfaDOaaaaabaaaaabaaaaabaaaaabaaaaDOaDTaDUaFgaFhaFiaFjaFkaDUaAYaaiaFlaFlaFmaFnaFoaFpaFqaFpaFraFsaFtaFlaFlaaiaEhauRaFuaaqaEjaosaHvaysaytaaqaztaFvaFwaFxaFyaFzaFzaFAaFBaFzaFBaFCaFDaFEaFFaFGaFHaFIaFJaFKaFKaFKaFLayRaaqaFMaxZaxZaxZaxZaxZaFNaaiaabaaaaaaaaaaoHaFOaFPaFQaFRaaaaaqaFSaFTaFUaFVaFWaFXaCuaCuaCuaFYaFZaCuaGaaaqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaabaGbayaaGcaAPaGdaGeaGfaGgaGhaGdaAPaGiaGjayaaGkaGlaySaxCaxCaxCaxCaxCaxCaxCaxCaGmaGnaEYaGoaGpaGqaEYaGraGsaCMaCMaCMaCMaCMaGtaGuaGvaDOaabaGwaGwaGwaGwaGwaGwaGwaabaDOaDTaDUaGxaGyaGzaGAaGxaDUaAYaaiaaiaaiaaiaGBaGCaDWaGDaDWaGCaGEaaiaaiaaiaaiaEhauRaGFaaqaEjaosaAuaysaytaaqaAvaGGaaqaaqaaqaaqaaqaaqaaqaGHaaqaaqaaqaaqaaqaaqaGIaaqaGJaGKaGLaGMaGNaaqaaqaFMaxZaxZaxZaxZaxZaFNaaiaaaaaaaaaaaaaaiaGOaGPaGQaaiaaaaaqaGRaGSaaqaGTaGUaGVaGWaGXaGYaGZaHaaDtaaqaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDwaEQaHbaHcaHcaHcaHcaHdaEQaDwaHeayaaHfaHgaySaHhaHhaHhaHhaHhaHhaHhaxCaHiaHjaEYaHkaHlaHmaEYaHnaHoaHnaHnaHnaHnaHnaHnaHnaHnaHpaaaaGwaHqaHraHsaHtaHuaGwaaaaDOaDTaDUaGxaHwaHEaHxaGxaDUaAYaaiaHyaHyaFmaHzaHAaFpaFqaFpaHAaHBaHCaFlaFlaaiaEhauRaEiaaqaHDaxQeHtaysaytaaqaztaGGaaqaHFaHGaHHaHHaaqaHIaHGaHJaaqaHKaHLaHMaaqaHNaaqaHOaHPaHPaHPaHQaaqaabaHRaHSaHSaHSaHSaHSaHTaabaaaaaaaagaaaaaiaHUaHVaHWaaiaaaaaqaHXaHYaaqaaqaaqaaqaaqaHZaaqaaqaaqaaqaaqaaqaaiaaiaaiaaiaaiaaiaaiaaiaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaaIbaIcaIbaIbaIdaIeaIbaIbaIcaIfaIgayaaERaIhaySaIiaIjaIkaIlaImaInaHhaxCaIoayVaEYaEYaIpaIqaHpaIraIsaItaIuaIvaIwaIxaIyaIzaIAaHpaabaGwaIBaICaIDaIEaIFaGwaabaDOaDTaDUaIGaIHaIIaIJaIKaDUaAYaaiaDVaDWaILaIMaGCaDWaINaDWaGCaIOaIPaDWaEgaaiaEhauRaIQaaqaEjazrazsaysaytaaqaIRaISaaqaITaHGaHGaHGaIUaIVaIWaIXaaqaIYaIZaJaaJbaJcaaqaJdaJeaJfaJeaJgaaqaaaaabaaaaabaaaaabaaaaabaaaaaaaaaaaaaaaaaiaJhaJiaJjaaiaJkaaqaaqaaqaaqaJlaJmaJnaJnaJoaJnaJpaJnaJqaJraJraJsaJraJraJraJraJtaJuaJvaaiaJwaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaaIfaIbaJxaJyaJzaJAaJBaJCaJDaJEaJFaJGaJHaJIaEPaERaJJaySaJKaJLaJMaJNaJMaJOaJPaxCaJQaJRaJSaJTaJUaJVaJWaJXaJYaJZaJZaJZaKaaJZaJZaKbaKcaHpaaaaGwaKdaICaKeaIEaKfaGwaaaaDOaDTaDUaKgaKhaKiaKjaKkaDUaAYaaiaKlaKlaFmaKmaHAaFpaKnaFpaHAaKoaFtaKpaKpaaiaKqawzaKraaqaEjazrabZabZabZabZaKsaKtaKuaKvaKwabZabZabZaaEabZabsaKxaKyaKzaKAabZaKBaaqaaqaaqaaqaaqaaqaaqaaqaaqaaqaaiaaiaaiaaiaoHaoJaaiaaiaaiaaiaaiaaiaKCaamaaiaKDaKEaKFaKGaKHaKIaKJabZabZabZabZaaEaKKaKLabZabZaKMabZaBbabZabZaaEaKNaaqaaqaKOaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiabAacOaaaaaaaaaaaaaaaaaaaaaaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJHaKQaKRaKSaJGaKTaJzaKTaJzaKTaJzaKTaJGaKUaKVaGdaERaKWaySaKXaKYaKZaLaaLbaLcaHhaLdaLeaLfaLgaLhaLiaLjaHnaLkaJZaJZaJZaJZaJZaJZaJZaKbaLlaHpaabaGwaLmaLnaLoaLpaLqaGwaabaDOaDTaDUaLraLsaLtaLuaLvaDUaAYaaiaaiaaiaaiaLwaGCaDWaGDaDWaGCaLxaaiaaiaaiaaiaLyaLzaLAaaqaHDaLBaLCaLCaLCaLDaLEaADabJaLFaLGabJaLHabJaLIabJaLJaxXaLKaLLaLMaaqaLNaLOaLPaLQaLQaLOaLRaLSaLSaLSaLSaLSaLTaLUaLSaLVaLWaLXaLYaLZaMaaMaaMbaMcaMdaMdaMdaMeaJuaMfaMgaMhaMiaaqaMjaMkaMlaaJaaqaMmaaqaMnaMoaMpaMqaMraMsaMtaMuaMvaMwaMxaaiaMyaMzaMAaMBaMCaMDaMEaMFaMGaMHaaaaaaaaaaaaaaaaaaaaaaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMIaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMJaJzaJzaIcaJGaKTaJzaKTaMKaKTaJzaKTaJGaKUaKVaGdaERaMLaySaySaMMaMNaMOaMNaySaySaySaySaySaMPaMQaMRaMSaHnaMTaMUaMVaJZaJZaMWaJZaMXaMYaMZaHpaaaaGwaGwaNaaNbaNaaGwaGwaaaaDOaDTaDUaNcaNdaNeaLuaNfaDUaAYaaiaDVaDWaNgaIMaGCaDWaGDaDWaGCaIOaNhaaiaaiaaiaNiaNjaNkaNlaNmabmaaiaaiaaiaaqaNnaNoaaqaNpaHGaaqaNqaaqaNraaqaNsaNtaNuaNvaNwaNxaNyaNzaNAaNBaNCaxSaNDaNCaNCaNEaNCaNzaNFaNzaJsaNzaNzaNGaNHaNIaNJaNJaNKaNLaNMaNNaNJaNOaJrabJaNPaNQaNRaNSaNTaNUaNVaaJaNWaNXaaqaNYaNZaOaaObaMraOcaMtaMuaMvaOdaOeaaiaOfaOgaOgaOhaMFaMFaMFaMFaMGaMHaaaaaaaaaaaaaaaaaaaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaJHaOiaKRaKSaJGaKTaJzaKTaJzaKTaJzaKTaJGaKUaKVaGdaERaOjaOkaOlaOmaOnaOoaDyaOpaOqaOraOsaOtaOuaOvaOwaOwaHnaOxaOyaOzaOAaOBaOCaODaOEaOFaOGayaaaaaabaaaaOHaOIaOHaaaaabaaaayaaDTaDUaOJaOKaOLaOMaONaDUaAYaaiaOOaOPaFmaOQaORaFpaOSaFpaOTaOUaOVaaiaOWaOXaOYaOZaPaaPbaPcaPdaaaaaaaaiaPeaPfaPgaaqaPhaHGaHGaHGaPiaHGaHGaHGaaJaPjaPkaaqaPlaosaaqaPmaaqaaqaPnaPoaPpaPqaPraaqaPsaPtaaqaPlaaqaaqaaqaaqaPuaaqaaqaosaaqaaqaaqaaqaPvaJuaaqaPwaNRaPxaPyaPzaPAaPBaPCaPDaPEaaqbDSaPGaPHaPIaPJaOcaMtaMuaMvaPKaPLaaiaPMaOgaOgaOhaMFaMFaMFaMFaMGaMHaaaaaaaaaaaaaaaaaaaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPNaPOaIbaJxaJGaJzaJzaPPaJzaJzaPQaJzaJGaJHaPRaPSaERaPTaPUaPVaPWaPVaPVaPVaPVaPVaPXaDyaySaPYaPYaPYaPYaPYaPZaQaaQbaHnaHnaHnaHnaPZaQcaQdaQeaQfaQgaQgaQhaQiaQjaQgaQgaQkaQeaQlaQeaQmaDUaQnaQoaQpaQqaQraaiaaiaaiaaiaQsaQtaQuaQvaQuaQwaQxaaiaaiaQyaOZaOZaOZaOZaQzaQAaQBaQCaQDaaiaQEaPfaQFaaqaaqaaqaaqaaqaaqaaqaaqaaqaaJaQGaQHaQIaQJaQKaQLaQMaQNaaqaQOaQPaQQaQRaQSaaqaQTaQUaQVaQWaQVaQXaQYaQZaRaaRbaRcaRdaReaRfaRgaaqaRhaMaaRiaRjaRkaPxaRlaPzaPAaRmaaqaRnaRoaRpaRqaRraObaObaaqaOeaMtaMuaMvaRsaRtaaiaRuaRvaRwaRxaRyaRzaMFaMFaRAaMHaaaaaaaaaaaaaaaaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPNaIbaIcaIbaIbaIdaIeaIbaIbaIcaPOaRBayaaRCaPTaCyaRDaRDaREaRDaRFaySaRGaRHaDyaRIaRJaRKaRLaRMaRNaRLaROaRLaRLaRLaRPaRLaRLaRQaRRaRSaRTaRUaRVaRTaRWaRTaRTaRTaRTaRXaRYaRZaRLaRLaSaaSbaScaSdaSeaSfaSgaShaSiaSjaSkaSkaSkaSkaSkaSkaSlaSmaSnaSoaSpaSqaSraSsaStaSuaOZaOZaSvaSwaSxaSwaSyaSzaSAaSBaSCaSDaSEaaqaSFaSGaSHaSIaSJaSJaSKaSLaSMaSNaaqaSOaSPaSQaSQaSRaaqaSSaSTaSUaSVaSWaSWaSXaSYaSZaSYaTaaTbaTcaTdaTeaaqaPvaTfaaqaTgaThaThaTiaTjaThaTkaaqaTlaTmaaqaTnaToaObaTpaaqaTqaTraTsaMvaOeaOeaaiaTtaaiabmafaaaiaaiaaiaaiaaiabAacOaaaaaaaaaaaaaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCyaTuaTvaHcaHcaHcaHcaTwaTuaCyaHeayaaTxaTyaTzaTAaTBaTCaTCaTDaySaTEaRHaTFaTGaRJaTHaTIaTJaTKaTKaYgaTLaTLaTLaTMaTNaTNaTOaTPaTQaTKaTKaTRaTSaTTaTUaTVaTVaTWaTVaTXaTSaTSaTSaTYaSbaScaSdaSeaSeaSeaSeaTZaSeaSeaSeaSeaSeaSeaUaaUbaUcaUdaUeaUfaUgaUhaUiaUjaUkaUkaUkaUlaUmaUmaUmaUnaSEaSEaSEaUoaUpaSEaaqaUqaUraSJaSJaUsaSJaUtaUuaSMaUvaaqaUwaUxaUyaUzaUAaaqaUBaUCaUDaUEaUFaUGaaqaUHaUIaUHaaqaaqaaqaosaaqaaqaPvaJuaaqaUJaNRaNRaNRaUKaNRaULaaqaaqaaqaaqaaqaaqaaqaUMaaqaMvaMvaMuaMvaUNaUOaaqaUPaUQaURaUSaUTaUUaUVaUWaUXaaaaaaaaaaaaaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaGbayaaTzaAPaGdaUYaUZaVaaVbaGdaAPaVcaVdayaaVeaPTaTzaVfaVgaTCaTCaTDaySaVhaRHaDyaTGaRJaViaVjaVkaRLaRLaVlaVmaVnaRLaVoaVpaVqaVpaVraVsaVpaVpaVtaVpaVpaVuaVvaVpaVwaVpaVxaRLaRLaRLaVyaVzaVAaVBaVCaVDaVCaVEaVFaVEaVEaVEaVEaVEaVEaVGaVHaVIaVIaVIaVIaVJaVIaVKaVLaVIaVIaVMaVNaVOaVOaVOaVOaVOaVOaVOaVPaSEaSEaaqaVQaVRaVSaVTaVTaVUaVVaUuaSMaVWaaqaaqaaqaaqaaqaVXaaqaVYaVZaWaaWbaQVaWcaaqaWdaWeaWfaWgaWhaWiaWjaWkaaqaPvaJuaaqaWlaWmaNRaWnaWoaNRaWpaWpaaqaWqaWraWsaaqaWtaWuaWvaMvaMvaWwaWxaOeaWyaaqaWzaUQaURaWAaWBaUQaUQaWCaWDaaaaaaaaaaaaaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaySaDwaTuaPSaERaDyaDyaESaPSaTuaPSaWEaWFaWGaWHaDwaWIaWIaREaWIaRFaySaWJaRHaDyaySaPYaPYaWKaPYaPYaPYaPYaPYaPYaWLaWMaPYaPYaPYaPYaPYaPYaWNaWOaWNaPYaWPaPYaWQaVjaWRaWSaWTaWUaRLaWVaPYaWWaWWaWXaWXaWXaWYaQCaQCaQCaQCaQCaQCaQCaaiaWZaXaaXbaXaaXcaXcaXdaXeaXfaXgaXhaaiaXiaQCaQCaQCaQCaQCaQCaXjaXkaXkaXkaaqaXlaXmaXnaXnaXnaXnaXoaKyaXpaXqaXraXsaXtaXuaXvaXwaaqaaqaXxaXiaXyaQCaXzaaqaXAaXBaXCaXCaXCaXCaXDaXEaaqaXFaJuaaqaXGaNRaWnaWnaWoaWnaNRaXHaaqaXIaXJaXKaaqaMvaXLaXMaXNaXNaXOaXPaXQaXRabZaXSaXTaXUaXVaUSaUQaUQaXWaWDaaaaaaaaaaaaaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCyaXXaDyaXYaXZaYaaYbaYcaYdaYbaYeaYfaYbaYbbcOaYhaYiaYjaYkaYkaYkaYlaYkaYmaYnaySaYoaYpaYqaYraYsaYtaYuaYvaYwaYxaYyaYzaYAaYBaYCaYDaYEaYFaYGaYHaYEaYIaPYaPYaYJaPYaPYaPYaPYaYKaYLaPYaYMaWWaYNaSeaSjaYOaaaaaaaaaaaaaaaaaaaaaaaiaYPaYQaYRaYSaYTaYUaYVaYWaYXaYYaYZaaiaaaaaaaaaaaaaaaaaaaaaaEFaZaaSEaZbaaqaZcaXmaXqaXqaXqaXqaXqaZdaZeaXqaXqaXqaXtaZfaZfaZgaZhaZiaZjaZkaZlaZmaZnaaqaZoaZpaZqaZraZraZqaZsaZtaaqaPvaZuaaqaZvaZwaNRaWnaWoaNRaZxaZxaaqaaqaZyaaqaaqaZzaWuaWxaZAaZAaZBaWxaOeaaqaaqaZCaUQaZDaZDaZEaZDaUQaZFaWDaaaaaaaaaaZGaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDwaZHaZIaZHaZHaZHaZHaZHaZHaZIaZHaZHaZJaDyaZKaZLaDyaDyaZMaDyaZNaZOaZPaZQaZRaySaYpaYpaZSaYraZTaYxaYxaYxaYxaYxaYyaZUaYxaYxaYxaYxaYEaZVaZWaZXaYEaYIaZYaZZbaababbacaYMbadbaebafbagbahbaiaYNaSeaSjaYOaaaaaaaaaaaaaaiaaiaaiaaibajbakbalbambanbaobapbaqbarbasbataaiaaiaaiaaiaaaaaaaaaaaaaEFaZaaSEaSEbauaXqbavbawbaxaXqbaybazaJabaAbaBbaCaXqaXtaZfaZfbaDbaEaZfbaFbaGbaHbaIaZfbaJbaKbaLaZqaZraZraZqbaMbaNaaqaPvbaOaaqaXGaNRaWnaWnaWoaWnaNRaNRbaPbaQaNRbaRaaqbaSbaTbaUaZAaZAbaVbaUbaWaaqbaXbaYaUQbaZbaZbbabaZaUQaXWbbbbbcbbdbbdbbeaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayaayabbfbbgbbgbbgbbgbbgbbgbbgaGjayaaySbbhbbiaySbbjbbjbbjbbjbbjbbkaySaySaySaySaYpbblbbmaYrbbnaYxaYxbbobbpbbqbbrbboaYxaYxaYxbbsaYEbbtbbubbvaYEaYIaZYbbwbbxbbybbzaYMbbAbbBbbCbbDbbEbbFbbGbbHaSjbbIaoJaaiaaiaaiaaibbJbbKbbLbbMbbNbbNbbObbPbbNbbQbbNbbRbbSbbTbbUbbVbbWaaiaaiaaiaaiaXibbXaZaaSEaSEaaqbbYbavbaBbaxaXqbbZbcaaXqbcbbccbaCaXqaXtaZfaZfbcdbcebcfbcgbchbcibcjaZfbckbaKbclaZqaZraZrbcmbcnbaNaaqaPvbcoaaqbcpbcqbcraWnaWobcsaNRaNRbctaNRbcubcvaaqbcwbcxbcyaZAaZAbczbcybcAaaqbcBbaYaUQaUQaUQaUSaUQaUQbcCbcDbcEbcFbcGbcHaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIaabbcJaGeaDAbcKbbjbcLbcMbcNbcRbcPbcQbhlbcSbbjbcTbcUbcVbcWaYrbcXaYxaYxbbobbqbcYbcZbboaYxaYxbdabdbaYEaYEaYEaYEaYEaYIaZYaZYaZYaZYaZYaYMbdcbbDbddbbDbdebbFaYNbdfaSjaSkaSkbdgbdhbdiaaibdjbalbdkbbNbbNbbNbdlbdmbdnbdmbdobdpbdqbdmbdrbdsbdtaaibdubdhbdvbdwbdxaZaaSEaSEbauaXqbdyaXqaXqaXqbdzbdAaXqbcbbdBbaCaXqaXtaZfaZfbdCbdDbdEbdFbdGbdHbcjbdIaaqbdJbclaZqaZraZraZqbcnbdKaaqbdLaaqaaqaaJaaqaaqbdMaWobdNbdOaNRbdPbdQaRlbdRabZbdSbdTbdUbdVbdVbdWbdXbdYabZbdZbeaaUQbebaUQaUSaUQaUQbecbedbbcbbdbbdbeeaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbefbegbehaERaZKbbjbcLbeibejbcLbekbelbembenbbjbeobepbeqberaYrbesbetbeubevbewbexbeybezbezbezbeAbeBaYrbeCbcUbeDbeEbeFbblbblbeGberbeHaYMbeIbeJbeKbeLbeMbeNaYNbdfaSeaSeaSebeObePbeQbeRbeSbeTbbNbeUbeVbeWbeXbeYbeZbfabfbbfcbfdbfebeSbffbfgbfhbfibfjbfkbflbfmbfnaSEbfoaaqaXqbfpbfqbaCaXqbfrbfsaXqbftbfubaCaXqaXtaZfaZfaZfaZgaZfbfvaZfbdHbcjbfwaaqbfxbclaZqaZraZraZqbcnbfyaaqbfzbfAbfAbfBbfCbfDbfEbfFbfGbfGbfGbfGbfGbfGbfHbfIbfJaZAaZAaZAaZAaZAaZAbfKbfLbfMbaYaUQaUQaUQaUSaUQaUQbfNaWDbfObfObfOaWDaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaabcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbfPbfQbfRbfSaZKbbjbfTbcLbfUbfUbfUbfVbcLbfWbbjbfXbfYbeqbfZbfZbfZbfZbgabfZbgbaYxbgcbgdbgebgebgfbggaYrbghbgibgjbgkbglbgmbgmbgnbgobgobgpbgpbgpbgpbgpbgqaWWaYNbgrbgsbgtbgubgvbgwbgxacFbgybeZbgzbgAaaiaaiaaiaaibgBaaibgCbgDbgEbgFbgzbgGbgHaaibgIbgJbgKbgLbgMbgNaSEaSEbauaXqbgOaXqaXqaXqaLLaXqaXqbgPbgPbgQbgQbgRaZfaZfbgSbgTaZfaZfaZfbgUbgVbgWaaqbaNbclaZqaZqaZqaZqbcnaXEaaqbgXbgYbgYbgZbgYbhaaWnaWnaWnaWnbhbaWnaWnaWnbhcbfLaZAaZAaZAaZAaZAaZAaZAbfKbfLbfMbaYaUQaZDaZDaZEaZDaUQbhdaWDbhebhfbhgaWDaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbhibhjbehbhkaWHbjQbcLbhmbfUbfUbfUbfVbhmbcLbbjbhnbhobeqbfZbhpbhqbhrbhsbfZbhtbhubhvaYrbhwbhxbhybhzaYrbblbhAbhBbhBbhCbhBbhBbhBbhBbhDbhEbhEbhEbhFbhEbhGaWWbhHbhIbhJaaiaaiaaiaaiaaiaaiaaqbhKaaqaaiaaibhLbhMbhNbhObhPbhQbhLafaaaiaaibhRaaiaaiaaiaaiaaiaaiaaibgNaSEaSEaaqbhSbhTaXqbhUaXqbhVaXqbhWbhXbhYbgQbhZaaqbiabibaaqaaqbicbidbidbidaaqaaqaaqbiebifbigbigbigbigbifbihaaqbiibgYbgYbgZbijaaqbikbilbimbinbiobipbiqbirbisaaqbitaMvbiuaZAaZAbiuaMvbivaaqbiwbaYaUQbaZbaZbbabaZaUQbfNaWDbfObfObfOaWDaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbixaDwbiybizbiAbbjbeibeibeibcLbiBbiCbiDbiEbbjbiFbiGbeqbfZbfZbfZbiHbiIbfZbiJbiKbiLaYrbhwbhxbhybiMaYrbblbhAbhBbiNbiObiPbiQbiRbhBbiSbiTbiUbiVbiWbiWbiWaWWbiXbiYbiZaaibjabjbbjcbjdbjebjfbjgbjhaaibjibhNbjjbjkbjlbjkbjjbhNbjmaaibjnbjobjpbjqbjrbjsbjtbjuaaibjvbjwbjwbjxaaqaaqaaqaaqbjybaubjybjzaaqaosaaqaaqaaqaaqaaqaaqbjAbjBbjBbjBbjBbjCbjDaaqbjEbjFbjEbjGbjGbjEbjFbjEaaqbiibgYbgYbjHbijaaqaaqaaqaaqaaqaaJaaqaaqaaqaaqaaqaaJbjIaQCaQCaQCaQCaXzaaqaaqbjJbjKaUQaUQaUQaUSaUQaUQbecbbbbjLbbdbbdbjMaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGbayabjNaHcbehaySaySaySaySaySaySbjObjPaySbbjbbjbbjbbjbbjccWbbjbbjbbjbjRbjRbjSbfZbjTbjUbiHbjVbfZbjWbjXbjWaYrbhwbhxbhybjYaYrbblbhAbhBbjZbkabkbbiQbkbbhBbiSbkcbkdbkebkfbkgbkhaWWbkibkjbiZbkkbklbkmbknbkobkobknbkpbkqaaibkrbhNbhNbksbktbjkbjjbhNbkubgEbkvbkwbkxbkybkzbkAbkxbkBaaibkCbkDbkEbkFbkGbkHbkIbkJbkJbkJbkJbkJbkJbkKbkLbkMbkNbkJbkObkJbkJbkJbkJbkJbkJbkJbkJbkPbkQbkRbkRbkRbkRbkRbkRbkSbkHbkTbkUbkUbkVbkWbkXbkWbkYbkWbkZblablbbkWblcbldbleblfblgblgblgblgblgblgblgblhblibljbljbljbljblkbljbllblmblnbloblpbcGblqaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaablrblrblrblrblrblrblrblrblrblraaaaabblsaGebltblublvblwblwblwblwblwblxblyblzblAblBblCbjSbfZbfZbfZblDbiIbfZaYraYraYraYrbhwblEblFblGaYrblHblIbhBblJblKbiQbkbblLbhBbiSblMbkdbkebkeblNblOaWWblPbkjbiZblQblRblSblTblUblVblWbkpblXaaiblYbksbhNblZbmablZbhNbksbmbafabmcbkxbkxbkybmdbkAbkxbmeaaibmfbkEbkEbkFbkGbkHbkJbkJbkJbkJbkJbkJbkJbmgbkJbkJbkJbkJbkJbkJbmhbmibmibmibmibmibmibmibmibmibmibmibmibmibmibmjbmkbmlblgblgbmmbgYbgYbgYbgYbgYbgZbgYbgYbgYbgYbgYbgYbgYbgYbgYbgYbgYbgYbmnbgYbmobmpaUQaUQaUQaUQaUQaUQaUQbmqbedbbcbbdbbdbbeaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaablrblrblrblrblrblrblrblrblrblrblrbefbegbmrbmsbmtaySbmubmubmvbmubmubmubmwberberberberbeqbfZbhpbmxbmybjVbfZbmzbmAbmzaYraYraYraYrbmBaYrbmCbhAbhBbmDbmEbkbbmFbmGbhBbiSbiWbmHbkebkebkebmIaWWbmJbkjbiZbmKbmLblSblTbmMbmNblWbkpbmOaaibmPbmQbhNbmRbmSbmTbjjbmUbmVbmWbmXbmYbmZbnabnbbncbkxbndaaibnebnfbkEbkFbkGbkHbkJbngbkJbkJbkJbkJbnhbnibnibnibnibnjbkJbkJbkJbkJbnkbkJbngbnlbkJbnmbnnbnobkJbnpbnqbnqbnrbnsbntbnubgYbgYbgYbgYbgYbgYbgYbnvbnwbnxbgYbgYbgYbgYbgYbgYbgYbgYbgYbgYbnybnzbnzbnAbnBbnCbnDbnEbnEbnEbnEbnFbnGbnHaabaaaaaaaabaKPaKPaKPaKPaKPaKPaaaaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaablrblrblrblrblrblrblrblrblrblrblrbnIbnJbnKbnLbnMaySbnNbnObnPbnPbnQbnRbnSbnTbnUbnUbnVbnWbfZbfZbfZbiHbnXbfZberberberberbnYbblbblbnZbgmboabobbocbodboebofbogbohbhBboibiWbojbkebkebkebokbolbombkjbonaaiboobopbknbknbknbknbkpboqaaiborabtaaiaaiaaiaaiaaiaaiaaiafaaaibosbotboubovbowboxboyaaibozboAboAaaiaaiaaiaaiaaiaaiaaiaaqaaqboBboCboDboDboCboBaaqaaqaaqaaqaaqaaqaaqaaqaaqaaqboEaaqaaqaaqaaqaaqaaiboFaosboGbgYbgYboHboHaaiaaiaaiaaiaaiboIbnzbnzbnybnzbgYbnzbnzbnzbnzboJaaiaaiaaiaaiboKaaiaaiaaiaaiaaiaaiaaiaaiaaiaaaaaaaaaaaaaKPaKPaKPaKPaKPaKPaaaaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaablrblrblrblrblrblrblrblrblrblrblrbhibhjbmrbmsboLaySboMbmuboNboObmubmubmuaZSboPboQboQboRbfZbhpboSbiHboTbfZboUboVboWboXboYboZboZbpaboZbpbbpcbhBbpdbpebiQbpfbpgbocbphbiWbpibkebkebpjbpkbplbombkjbpmaaibpnbpobppbpqbprbpsbptaaiaaibpuaaibpvbpwbpxbpwbpyaaiaaaafaaaibpzbpAbpBbpCbowbkxbpDaaibpEbpFbpGaaibpHbpIbpJbpKbpLbpMbpNbpObpPbpQbpRbpRbpQbpSbpTbpUaaqbpVbpWbpXbpYaaqbpZbqabqbbqcbqdbqebqebqfaaibqgabmaaibqhaaibqibqiaaibqjbqkbqlaaibqmbqnbqmaaibqobnzboJaaibqpbqqbqpaaibqrbqsaaibqtbqubqvaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaKPaKPaKPaKPaKPaKPaaaaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaablrblrblrblrblrblrblrblrblrblraaabqwaTzbqxbizbqyaySbqzbmubqAbqBbqCbqDbmubqEbqFbqGbqHboRbfZbfZbfZbfZbfZbfZbqIbqJbqKbqLbqMbhBbhBbhBbhBbhBbhBbhBbqNbhBbhBbhBbqObhBbqPbqQbqRbkebkebkebqSbolbqTbkjbqUaaibqVaaJaaqaaqaaqaaibqWaaibqXbqYacFbqZbrabrbbrcbrdachbrebrfaaibrgbkxbrhbribowbrjbkxaaibrkbrlbrmaaibrnbrobrpbrqbrrbrsbrtbpRbpRbpRbpRbpRbpRbpRbrubrvbrwbrxbrybrzbrAaaqbrBbrCbrDbrEbrFbrGbrCbqfaaibrHabmbrIbrJbrKbrLbrLaaqbrMbrNbrObrPbrQbrRbrSaaiaaqbrTalYaaibrUbrVbrWbrXbrXbrYaaibrZbsabsbaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaKPaKPaKPaKPaKPaKPaaaaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGbayabjNaHcbhjbbgbbgbbgbscbbgbsdaERbsebsfaySbsgbshbsibsjbskbslbsmbcWbblbblbblbsnbnUbnUbnUbnUbnUbnUbsobspbspbsqbsrbhBbssbstbsubsvbswbsxbsybszbsAbsBbsCbsDbphbolbqRbkebkebsEbiWaWWbsFbsGbsHachbsIbsJbsKbsLabJbsMbsNachbsObsPachbsQbsRbsQbsRbsSachbrebsTachbsUbsVbsWbsXbsYbsZbtaachbtbbpFbpFaaibtcbtdbtebtfbtgaaibrtbpRbpRbpRbpRbpRbpRbpRbthbtibtjbtkbtlbrxbtmaaqbtnbtobtpbrEbqfbrGbtqbtraaibtsbttbtubtvbtvbtwbtxbtybtzbtAbtAbtAbtBbtAbtCbtDbtEbtFbtGbtDbtHbtIbtJbtJbtJbtKaaibtLbsabtMaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaKPaKPaKPaKPaKPaaaaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaMIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtNbtObtPbtQbtRbtSbtSbtTbtUaDyaySbtVbtWbsjbtXbmubmubmuberbtYbtZbuabubbuabuabuabubbuaberberbhBbhBbhBbucbhBbudbudbudbudbudbudbsybuebufbugbuhbuibujbukbulbumbunbuobupbuqburbusbutbuubuvbuvbuwbuxabZbuybuzacFbuAbuBaaibuCbrcbuDbrabuEaaiaaabuFaaiabmbuGaaiaaiaaiaaibuHaaibuIbpFbuJacFbuKbuLbuMbuNbuOaaibuPbuQbuRbuSbuTbuUbuVbuWbrubuXaaqbuYbtlbuZbvaaaqbvbbvcbrDbrEbqfbrGbrCbqfaaibrHabmbvdbvebvfbvgbvhaDpbvibvjbvkbvlbvmbvnbvoaaibvpbvqbvraaibvsbvtbvubrXbvvbvwaaibtLbsabvxaaiaaaaaaaaaaaaaabaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaabtNbvybvzbvAaDxaDxbvBbvCaDxbvDaySbvEbvFbvGbvHbmuaaaaaaaaaaabaabbvIbvIbvIbvIbvIbvIbvIaaaaaabvJbvKbvLbvMbvNbudbudbudbudbudbudbvObvPbvQbvRbvSbvTbvUbvVbiWbiWbvWbiWbiWbvXbvYbvZbwaaaibwbaaqaaqaosaaqaaJbwcaaibwdbuBaaibwebpwbpwbpwbwfaaiaaabuFaaibwgbwhbwibwjbwkabJbwlabJbwmbpFbwnaaibpHbwobwpbwqbwrbwsbwtbwubwvbwwbwxbwybwzbwAbwBbwCboCbwDbtlbwEbwFaaqbwGbwHbwIbwJbwKbwLbwMbqfaaibwNbwObwPbwQbwQbwRbwSbwTbwUbwVbwWbwXbwYbwZbxaaaibxbbvqbxcaaibxdbxebxfbrXbrXbxgaaibrZbsabxhaaiaaaaaaaaaaaaaabbxibxjbxkbxjbxkbxjbxlaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabxmaDwbxnbxnbxobbgbxpaGbayabxqbxpaySbxrbxsbxtbxubmuaaaaaaaaaaaaaaabvIbvIbvIbvIbvIbvIbvIaaaaaabxvbxwbudbxxbxybxybxybxybxybxzbxAbxybxBbxCbxDbxEbxFbxGbxHbiWbxIbkebxJbxKbxLbxMbxNbxOaaiaaiaaibxPbxQbxRbxSbxTaaibpubuBaaibxUbxVbxWbxXbxYaaiaaabxZaaibyabybbycaaqbydaaqbyeaaqbyfbpFbygaaiaXibyhbyibyjbykaaqbylbymbynbyobypbypbyqbyrbysbytaaqaaJbyubyvaaqaaqaaqaaJbywaosaaqaaiaaiaaibyxbyyabmbyzbvebvfbyAbwQbyBbyCbyDbyDbyEbrObyFbyGbyHaaibrTbyIaaibyJbyKbrXbyLbyMbyNaaibtLbyOaaiaaiaaaaaaaaaaaaaabbyPbyQbyRbySbySbyTbyPaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvIbvIbvIbvIbvIbvIbvIbyWbyXbyYbyZbudbzabudbzbbzbbzbbzbbsybuebudbudbufbzcbzdbzebzfbzgbzhbzibkebkebzjbzkbxMbxNbzlbzmbznbzobzpbzqbzrbzsbztaaibzubzvacFbzwbzxbzybzzbzAachbrebzBaaibzCbzDbzEaaqbzFaaqbzGaaqbzHbpFbzIaaibzJbzKbzLbzMbzNabJbzObzPabJabJbzQbzRabJabJbzSbzTaxSaxVbzUbzVbzWbzXbzYbzZbAabAbbAcaaibAdbAebAfbAgabmbAhbAibAjbAkbAlaaqbAmbyDbyDbAnbAobyFbApaaibAqbAqbAraaibAsbAtbAubAvbrXbAwaaibtLbAxaaiaaaaaaaaaaaaaaaaabbAybAzbyRbySbyRbAAbxkaabaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvIbvIbvIbvIbvIbvIbvIbABbACbABbADbAEbzabudbudbudbudbudbsybuebAFbhBbhBbAGbkebuhbzfbAHbAIbAJbAKbAKbALbAMbANbAObAPbAQbARbASbATbAUbAVbAWbAXaaibwdbuBaaibAYbAZbBabBbbBcaaiaaabxZaaiabmaaiaaiaaiaaiaaibBdaaibBebpFbzIaaibBfbBgbBgbBhbBiaaqbBjbBkbBlbBmbBnbBobBpbBlbBqbBrbBsbBtbBubBvbBwbBwbBxbBybBzbBAbBBbBCbBDbBEbBFbBGbBHbBIbBIbBJbBKbBLaaqbBMbrObrObBNbBObyFbBPbBQbBRbBSbBTaaqbBUbBVaQDbBWbjEaaiaaibBXaaiaaibBYbBZbBZbBZbCaaaibyPbySbyRbySbySbCbbyPaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaagaaaaaaaaabvIbvIbvIbvIbvIbvIbvIbCcbCdbCcbCebudbzabudbzbbzbbzbbzbbsybuebCfbCgbhBbChbkebuhbzfbCibCjbCkbkeblNbkebClbxMbpFbCmaYObARbCnbCobCpbCqbCrbCsborabtbCtaaiaaibCubCvbCwaaiaaiaaabxZaaibCxbCybCzbCAbCBbCCbCDachbCEbpFbzIbwsbCFbCGbCHbCIbCJaaqbCKbCLbCMbCNbCObCPbCQbCRbCSbCTbCUbCVbCWbCXbCYbCZbDabDbbDcbDdbDeaaibDfbDgbDhbDiaaibDjbDkbDlbDmbDmaaqbDnbDobDpaaqbDqbyFbDraaqbDsbDtbDubDvbDwbDxbDybDzbDAbDBbDCbDDbDEbDFbDGbDGbDHbDIbDJbDKbDLbxjbxkbDMbxkbxjbDNaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvIbvIbvIbvIbvIbvIbvIbDObyXbDPbDQbudbzabudbudbudbudbudbsybuebCfbDRbhBbFnbkebDTbDUbkebDVbkdbkebkebDWbxLbxMbpFbCmaYObARaaibDXbDYbDZbEabEbabmbEcbEdbEeachachbEfbEgachbrebrebEhaaibEibEjbEkbElbEmbEmbEnbEobEpbpFbEqaaiaaqbErbjEbEsbEtaaqbCKbEuaaqbEvbEwbExbEyaaqbCKbEzbEAaaqaaqaaqaosaaqaaqaaqbEBamfaaqaaiaaibECaaqaaqaaiaaiaaqaaJaaqaaqaaqaaqaaqaaqaaqbEDbEEbEFaaqbEGbEHbEIbEJbEJbEKbELbEMbENbEObEPbEQbERbESbETbETbEUbDwbEVaaibEWbEXbEYbEZaaibFaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvIbvIbvIbvIbvIbvIbvIbCcbCdbCcbFbbFcbFdbudbudbudbFcbudbsybuebCfbFebhBbFfbkebuhbzfbkebolbFgbkebkebFhbzkbxMbpFbFibFjbFkaaibFlbFmeHrbFobFpabmbFqbFrbFsbFtbFubFvbFwaaqaaaaaaaaaaaibFxbFybFzbFzbFAbFBbFCaaibFDbFEbzIbFFbFGbFHbFIbFJbFKbFLbFMbCLbjEbFNbFObFPbFQbjEbCKbEzbFRbFSbFTbFUbFVbFWaaqbFXbFYbFZaaqbGabGbbGcbGdbGebGfbGgbDBbGhbEJbEJbGibGjbEJbGkbGlbGmbGnbGobEJbGpbGqbGrbGsbGtbGuaaiabmaaiaaiaaibBXaaiaaibBYbCaaaibGvbGwbGxbGybGzbGAbGBbGCaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvIbvIbvIbvIbvIbvIbvIbGDbGEbGDbGFbGGbGHbGHbGHbGHbGHbGIbGJbGKbCfbGLbhBbGMbGNbGObGPbGQbvUbGRbGSbGTbiWbvXbGUbpFbGVbGWbARaaibGXbGYbGZbDYbHaabmbHbbHcbHdaaqbHebzybHfaaqaaaaaaaaaaaibHgbHhbHibHjbFAbFBbFCaaibHkbHlbHmbHnbHobHpbHqbHrbHsbHtbHubHvaaqaaqbHwbHxaaqaaqbCKbEzbHybHzbHAbHBbHCbHDaaqbHEbHFbHGbHHbHIbHJbHKbHKbHLbHMbHNbHObHPbDwbDwbHQbDwbHRbDwbHSbDwbHTbHUbHUbHVbHWbHXbHYbHZbIabIbbIcbIdbIeaaibIfbIgaaaaaaaaaaaibIhbIibIjbIkbIlbImbInaaiaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvIbvIbvIbvIbvIbvIbvIbIobIpbIqbhBbhBbIrbyXbyXbyXbIsbhBbhBbItbIubIvbhBbIwbIwbIwbIxbIwbIybIzbIAbIBbICbvXbxMbpFbIDaaqaaqaaiaaiaaiaaiaaibIEabmaaibCtabmabZaosbIFaaqaaqaaiaaiaaiaaiabmaaiaaiaaiaaiaaiaaiaaibIGbpFbIHboCaaqbIIbIJaaqaaqbCKbIKbILbIMbINbIObIPbIQbIRbFMbISbITbIUbIVbIWbIXbIYbIZbJabJbbJcbJdbJebJfbJgbGcbJhaaiaaiaaiaaiaaiaaibJiaaiaaiaaiaaJbJjaaqaaqbJkbJlbJmbJnbHYbJobJpbJqbJrbJsbJtaaibIfbJuaaaaaaaaaaaibJvbJwaaibDKaaiaaibDKaaiaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvIbvIbvIbvIbvIbvIbvIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabJxaabaaaaaaaaaaaabIwbJybJzbJAbJBbIybJCbJDbJEbJFbvXbxMbpFbJGbJHbJIbJJbJKbJLbJMbJNbJObJPbJQbJRbJSbJTbJUbJVbJWbJXbJYbJZbKabKbbKcbKdbKeboAbKfbpFbKgbKhbKibpFbKjaaqbKkbKlbKmbKnbKobCKbKpbKqbKrbKsbKtbKubKvbKwbKxbKybKzaaqbKAbHBbKBbKCbKDbKEbKFbKGaaqbKHbGcbGcbGcbKIaaibKJbKKbKLbKMbKNbKObKPbKQaaibKRbKSbKTaaqaaqbKUbJmbKVbKWbKXbKYbKZbLabLbbLcaaibLdaaiaaaaaaaaaaaiaaiaaiaaiaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMIaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvIbvIbvIbvIbvIbvIbvIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIwbLebLfbLgbLhbLibLjbLkbLlbLmbvXbxMbLnbLobpFbpFbzIbLpboAbKebKdbLqbLrbLqbLsbLtbLtbLubLvbLwbLtbLtbLxbLtbLybLtbKdbKeboAbLzbLAbLBbLCbLDbLEbpFaaqbLFbKlbLGbLHbLIbCKbLJbLKbLLbLMbLNbLObLPbLQbCKbLRbLSaaqbLTbLUbLUbLVaosbLWbLXbLYaaqbLZbMabGcbMbbMcaaibKJbMdbMebMfbMgbMhbMibMjaaibMkbKSbMlbMlaaqbMmbMnbMobMpbMqbMrbMsbMtbMubMvaaibIfaaibMwaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvIbvIbvIbvIbvIaaaaaaaaaaaaaaaaaaaaaaaabMxbMybMzbMybMAaaaaaaaaabIwbIwbMBbMCbLgbMDbMEbMFbJEbMGbMHbvXbxMbMIbMJbMKbMLbMMbMNbMObMPbMQbMRbMSbMTbMUbMVbMVbMWbMXbMXbMXbMXbMXbMXbMYbMZbNabNbbNcbNdbMLbNebNfbNgbNhbNiaaqbNjbKlbKmbNkbLIbCKbLJbLKbNlbNmbNnbNobNpbNqbCSbNrbNsaaqaaqbNtbNuaaqaosaaqaPCaNPaaqbNvbNwbNxbNybNzaaibKJbNAbNBbKMbNCbNDbNEbNFaaibNGbKSbMlbMlaaqbNHbNIbNJacFbNKbNLbNMbNNbNObNPaaibIfaaibNQaaiaJkbNRaJkaJkaJkaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabNSbNTbNUbNVbNSbNWbNXbNYbIwbNZbOabObbOcbOdbOebOfbOgbOgbOhbvXbOibOjbOkaaqaaqbOlbOmbOnaaqaaqaaqbOobOpbOqaaqaaqbOrbKdbKdbOsaaqaaqaaqaosbOtaaqaaqaaqbOuaaqaaqbOvaaqbOwaosaaqbOxbOybOzaaqbOAbOBbLJbOCaaibODbOEbOFbOGaaibCKbLRbOHaaqbOIbOJbOKbOLbOMbONabJbOObOPbOQbORbOSbOTbOUaaiaaiaaiaaiaaiaaiaaiaaiaaiaaibOVbOWbOXbOXaaqbOYbOZbPaaaiaaiaaiaaiaaiaaiaaiaaibIfaaibPbbPcbPdbPebPebPfaJkaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbPgbBZbBZbCaaaqaaqaaiaaiaaiaaibPhaabaabaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabMzbPibPjbPibMzbPkbPlbPmbPnbPobPpbPqbPrbPsbIybPtbPubPvbPwbIybOjbOjbPxaaqbPybPzbPAbPBbPCaaqbPDbPEbPFbPGbPHaaqbPIbPJbPKaaqbPLbPMbPNbPObPPbPQbPRbPSbPTabZbPUbPVbPWbPXbPYbPZbQabQbbQcbQdbQebQfbQgbLKbQhbQibQjbQkbQlbQmbCSbQnbQobQpbQqbOKbQrbQrbQsbQtaaqbQubQvbQwbQxbQybQzbQAaaibQBbQCbQDbQEbQDbQDbQFacFacFbQGbQHbQIbQJaaqbQKbQLbJnaaibsabQMbQNbQObQObQNbQObQPaaibQQbQRbPdbPebQSbQTaJkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabQUbQVbQWbQVaaqaaiaaibQXbQYbQXbQZaaiaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabNSbPibPibPibRabRbbMCbRcbRdbRebMCbPqbRfbRgbIybIybIybIybIybIybRhbOjbRiabZbRjbRkbRkbRkbRlaaqbRmbRnbRnbRnbRoaRibRpbRqbRrabZbRsbRtbRubRvbRwbRxaaqaaqbRyaaqbRzbRAbRBbRCbRDaaqbLFbKmbLGbLHbREbRFbRGbRHacFbRIbRJbRKbRLaaibRMbRNbROabZbRPbRQbRRbRSbRTbRUaaqaaqaaqaaqaaqaaJazraugaaibRVbQDbQDbRWbQDbRXbRYaaiaaibRZbKSbSabSaaaqbJlbSbbJnaaiaaibScaaiaaiaaiaaiaaiaaiaaibSdbSeaJkbSfbSgbShaJkaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacbSibQVbQVbSjaaiaaibQXbQXbSkbQXbQXaaiaaiaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabMzbPjbPjbPjbMzbSlbSmbSnbSobSpbMCbSqbSrbSsbStbSubSubSubSvbOjbOjbOjbPxaaqbRlbRkbSwbRkbSxaaqbSybRnbSzbRnbSAaaqbSBbSCbSDaaqbSEbSFbSGbSHbSIbSJabJbSKbSLabJbSMbSNbSObSPbSQaaqbNjbKmbKmbSRbREbRFbSSbSTbSUbQibSVbSWbSXbSYbSZbTabTbbTcbTdbTebTfbTfbQrbTgaaqbThbTibTjbTkbTlbTmbTnaaibRVbTobQDbQDbQDbTpbTqaaiaaibTrbKSbSabSaaaqbTsbTtbJnaaibTubTvbTwaaibTxbTybTzbTAbTBbTCbTDaJkbTEbTFbTGaJkaaiaaiaaiaaiaaiaaiaaiaaiaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaabTHaaibSiaaiaaibQXbQXbQXbQXbQXbQXbQXaaiaaiaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaabNSbTIbTJbTKbNSbTLbNXbNYbIwbIwbTMbTMbTMbIwbIwbOjbTNbTNbTObTPbOjbTQbTRaaqbRlbRkbRkbRkbTSaaqbSybRnbRnbTTbTUabJbTVbTWbTXaaqaaqaaqaaqaaqbTYaaqaaqbTZbUaaaqaaqbUbaaqaosaaqaaqbUcbUdbUdaaqaaqbUebUfbUgbUhbUibUjbUkbUlbUmaaqbUnbTbbUobUpbUqbUrbUsbUtbUuaaqbUvbUwbUxbUybUzbUAbUBaaibUCaaibUDbUEbUFaaiafaaaiaaibUGbUHbSabSaaaqbUIbSbbJnbUJbUKbULbUMbUNbUObUPbUPbUQbURbUSbUTbUUbUVbUWbUXbUYbUZbVabVbachbVcbVdbVebVfaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaaaaqaaibVgbVhbVhbQXbQXbQXbQXbQXbQXbQXbQXaaiaaiaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabVibMybVjbMybVkbVlaabaaaaaabIwbVmbVnbVobIwaaabOjbVpbVqbVrbVsbVtbVubVvaaqbVwbVxbVybRkbRlaMgbVzbVAbVBbVCbVDaaqbVEbVFbVGbVHbVIbVIbVIbVIbVJbVKbVLbVMbVMbVNbVNbVObVPbVQaaqaaqbVRbVSbVTbVUbVVbRFbVWbUgbVXbVYaEmbVZbLPbWaaEmbWbbWcaoaaoabWdaoaaoaaoabWeaaqbWfbWgbWhbWibWjbWkbWlaaibWmbWnbWobWpbWqbWnbWrbWsaaqbWtbWubKTaaqaaqbWvbWwbWxacFbWybWzbWAacFbWBbWCbWDbWEbWFbWGbWHbWIbWJbWKbWJbWLbWKbWKbWKbWMbWNbWObWPbWQaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaiaaibWRbQXbQXbQXbQXbQXbQXbQXbQXbQXbQXbQXaaiaaiaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabbWSbOjbOjbOjbWTbOjbOjbWUaaqbWVbWWbWXbWYbWZaaJbXabXbbXcbXdbXeaMgbXfbXgbXhabJachachachachbmWbXiborabZbXjabZabZbXkbXlbXmbXnbXobXpbXqbXrbXsbXtbXubXvbXwbXxbXybXzbXAbXBbXCbXDbXEbXFbXFbXFbXGbXHbXIbXJbXKaaqaaqbXLaaqamfbXMbXNbXOaaibXPbXQbXRbXSbXRbXTbXUbXVaaqaaqbXWaaqaaqbXXbXYbSbbvqaaiaaibXZaaiaaibYabYbbYcbYdbYebWKbYfbYgbYhbWDbYhbWDbYibWDbWDaaibYjbYkbYlbYmaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaaaaibQXbQXbQXbQXbQXbQXbYnbQXbYobQXbQXbQXbQXbQXaaiaaiaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWSbYpbYqbYrbOjbYsaaqbYtbYubYvbRlbYwaMhbYxbSybYybYzbYAaMhbYBbYCbYDaaiaaibYEbYFbYGbYHbYIabmbYJbDgbYKaaqbYLbDgbDgbYMabZbYNbYObYPbXsbYQbYRbYSbYTbYUbYVbYWbYXbYYbYVbYVbYZbZabZabZabZbbZabZcbZabZdbZebZfbZgbZhbZibZjbZkbZlaaibZmbZnbZobZpbZobZqbZrbXRbZsbZtbZubvqbZvbvqbXYbSbbvqaaibZwbZxbZyaaiaaiaaiaaiaaibZzbWDbZAbZBbYibWDbZCbWDbSdbWDbZDaaibZEbZFbZGaaiaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaibZHbZHbZHbZHbZHbZHbZIbQXbZJbZHbYobQXbQXbQXbQXaaiaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWSbZKbZLbZMbOjbYsaaiaaiaaiaaiaaiaaiaaqaaqaaqaaqaaqaaqaaqbZNbZObZPbZQbZRbZSbZTbZTbZUbZVabmbDgbDgbZWaaqbZXbDgbDgbDgbZYbZZcaabXqcabaEmcacbZacadcaecafbLJcaecagbXFbXFbXFbXFbXFbXFcaebXFbXFbXFbLJcahcaicajcakcalcamcancaoaaicapcaqbXRcarbXRcascatcaucavcawcaxcaybvqcazbXYbSbcaAaaibyOcaBcaCcaDaaiaofaofaaicaEcaFcaGcaHcaIcaJcaKcaLcaMcaNcaOaaicaPcaQcaRcaSaacaacaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaacaTbQVbQVbQVbQVbQVbQVbQVcaUbQYbQXbQXbQXbQXcaVbQYaaiaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWSbWSbWSbWSbOjbYsaaiaaaaaaaaaaaaaaicaWcaXcaYcaZcbacbbaaqcbccbdcbecbfcbgcbhcbicbicbjcbkabmaaiaaiaaiaaicblaaibDgbDgaaqcbmcbncbocbpcbqcbrcalcbscbtcbucbvcbwcbxcbybXFbXFcbzcbAcbBcbCcbBcbAaaiauiacFacFcbDcbEcbAaaqcbFcbGaaicbHcbIcbJcbKcbLcbMcbNaaiaaiaaiabmaaiaaiaaicbOcbPcbQaaibsacaBcbRcbSaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaibVhbVhbVhbVhbVhbVhcbTbQXbVgbVhcbUbQXbQXbQXbQXaaiaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacbVaaaaabaabaaiaaiaaiaaiaaiaaiaaiaaiaaqbWUcbWaaacbXcbYcbZccaccbcccccdcceccfccgabZcchcciccjcckcclccmccnccoccpccqabmccrccsccsccscctaaibDgbDgaaqaaqaaqaaqaaJaaqccuccuccvaaqaaqaosaaqaNtccwccxccyccxachcczccAccBachbrebreachccCccDccEaaiccFccGbVQaaiaaiabmaaiccHaaiccIccJaaiccKccLccMbDgccNaaiabmccOafaaaibsacaBccPbsaccQccRccSccTbsabsabsabsabsabsaccUccVbIgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaibQXbQXbQXbQXbQXbQXbYnbQXcbUbQXbQXbQXbQXbQXaaiaaiaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaccXccYccYccYccZcfAcdacdbcdccddcdeaaqcdfbWUaEFaaacdgcdhcdicdjcdkccccdlcdmcdncdoaaqcdpbYCbTWcbfcdqbZTcdrbZTcdscdtcducdvcdwcdwcdwcdxaaibDgbDgaaqcdycdzcdAcdBcdCcdDcdDcdEcdFcdGcdHcdIcdJabZcdKbXJbXJacFcdLcdMcdNaaiaaaaaaaaicdOcdPcdQachcdRcdScdTcdUcdUcdVbBDcdWcdXcdYcdZcdXcdXcdXceacdXcdXcebceccedceecefcegcehceibQOcejbQObQObQObQObQOcekcelbQObQOcembsacenaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaaibWRbQXbQXbQXbQXbQXbQXbQXbQXbQXbQXbQXaaiaaiaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceocepcepcepcepceqcercescetceuceucevaaqcewbYsaEFaaacdgcexceycezceAceBceCceDceAceAceEceFceGceHacFacFceIceJbZTceKceLceMcdwcdwcdwcdwceNaaibDgbDgaaqceOcePceQceRceSceTceTceUceVceWceXceYceZaaqcfabXFcfbaaicfccdMcfdaaiaaaaaaaaicfecffcfgaaibDhcfhcficficficficficficfjcfkcflcfmachachcfncfoachachcfpcfqcfraaqaaicfscftcfuaaiaaiaaiaaicfvcfwcfuaaiaaibsacfxbsabJuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabTHaaiaaibZHbZHbQXbQXbQXbQXbQXbQXbQXbQXaaiaaiaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacfycfzcfCcfBcfCcfEcfDcgQcfFcfFcfGaaqcfHbWUaEFaaacdgcfIcfJaiVcfKccccfLcfMcfNcfOaaqcdpbYCbYDcfPaaicfQaaqcfRcfScfTcfUcfVcdwcdwcfWcfXaaibDgcfYaaqcfZcgacgbcgccgccgccgdcgecgccgccgfcgbcggaaicghbXFcgiaaicgjcdMcgkaaiaaaaaaaaicglcgmcgnaaicgobDgcfYaaiaaiaaiaaiaaiaoHaoIaoJaaiaaicgpcgqcgrcgsaaicgtcguamdaaicgvcgwcgwcgwcgxcgycgzcgAcgBcgCcgDcgEaaicgFcgGcgHcgIcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgKcgLaaibSiaaibQXbQXbQXbQXbQXbQXbQXaaiaaiaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaacfycgMcgNcgOcgPcetchYcetcgRcetcgScgTcgUcgVcgWaaacgXcbYcgYccacgZccccccchachbchcabJchdchechfchgaaichhchichjchkchlabmchmcdwcdwcdwchnaaibDgbDgaaqaaqaaJchochpchqchraaqchschtchuchvbUgaaJaaicfabXFcfbaaichwcdMcdNaaiaaaaaaaaichxchychzaaibDgbDgbDgaaiaabaaaaaaaabaaaaabaaaaaaaaichAchBchCchDchEchFchGchHchIchJchKchLchLchMchNchNchOchPchQchQchRaaiaaichSaamaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaichTchUchVaaiaaibQXbQXchWbQXbQXaaiaaiaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacfychXcfCchZcfCciacibcidciccgQcifaaqbYrcigaaiaaaaaaaaaaaaaaicihciicijcijcikcilaaqcimbYCbTWcinciocipciqcircircirciscitcdwciucdwcivaaibDgbDgaaqciwcixciycizciAciBaaqciAciBcizciCciDciEaaicghciFcgiaaichwcdMciGaaiaaiaaiaaiaaiaaiaaiaaiciHbDgbDgaaiaabaaaaaaaaaaabaabaabaaaaaiciIciJciJciKciLciMciNciOciPciQciRciSciTciUciVciWchNchNchNciXciYaaiciZcjacjbaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacjccjdcjebSjaaqaaiaaibQXbQYbQXaaiaaiaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOabAaaiaaiaaiaaiaaiaaiaaiaaiaJkaJkaJkaJkaJkaaiaaqaaqaaqaaqaaqaaqcjfcjgaaiaaiaaiaaiaaiaaiaaqaaqaaqaaqaaqaaqaaqcjhbYCbTWcjicjjcjkcjlcjmcjncjocjpcjqcjrcjscjtcjuaaibDgbDgaaqcjvcjwciycizcizcjxaaqcjycizcizciCciycjzaaiaaiaaiaaiccIcjAcdMcjBaaicjCbDgbDgbDgbDgcjDbDgbDgbDgbDgaaiaaaaaaaaaaaaaaaaabaabaaaaaicjEcjFcjFcjGcjHcjIcjJcjKcjLcjMcjNchNchNchNcjOcjPchNcjQchNciXcjRaaicjScjTcjUaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacjVbBZbBZbCaaaqaaqaaiaaiaaiaaibPhaabaabaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacjWcjXcjYcjZckackackbckcckdckeckfckgckhckickjckjckjckkcklckmckncknckockpckqckrcksckrckrckrckqckrckrcktckuckvckwbYCbTWckxckyckzafaaaicfUacFaujckAckBacFatEcblaaibDgbDgaaqckCckDckEckFckGckHaaqckIckGckJckKckEckLaaibDgbDgbDgckMchwcdMchwckNbDgbDgbDgbDgbDgbDgbDgbDgbDgbDgaaiaaaaaaaaaaaaaaaaabaabaabaaickOckPckPckPcbAaaickQafacbAckRckSckTckTckUcjMcjMckVckTckWckXckYaaickZclaclbaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacjWcjXclccldclecldclfclgclhclicljclkcllclmclnclnclnclnbYCbTXbTXbTXclncloclnclnclnclnclnclnclnclnclnclnclpclqclrclscltcluclvclwclxaaiclyclzclAclBclCclDclEclFachcficlGabJclHclIclJclKcizclLaaqclLcizclKclMciyclNaaiclOachachbmWclPclQclRaaibNtaoIaoIbNuaaiaaiaaiaoHaoIaoJaaiaaaaaaaaaaaaaaaaaaaabaabaaiclSclTclUclVaaiclWclXclYaaiclZcmacmacmacmbcmccmdcmecmacmacmacmfaaiaDpcmgcmhaFRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacjWcmicldcmjcmkcmlcmmcmncmocmpcmqcmrcmscmtcmucmvcmwcmwcmxabJcmyabJcmucmzcmucmucmucmucmucmucmucmucmucmucmAclncmBcmCcmDcmEcmFcmGcmHcmIcmJcmKcmLcmMcmNcmOcmPcmQacFbXlcmRcmScmTcizciycizcizcmUabZcmVcizcizciCciycmWaaicmXaaiaaaafaaaicmYaaiaaiaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaaiaaiaaiaaiaaiaaiaaiaaicmZcnacnbaaiaaicnccndcneaaiaaiaaiaaicnccndcneaaiaaiaEFcnfaEFaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOabAaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaicngaaqaaqcnhaaqcniaaqaaqcnjaoJaaqaaqaoHaoIaoJaaqaaqaaqaaqcnkcnlcnmcnncnocnpcnqcnrcnscnrcnrcntcnrcnucnvcnwcnxcnyaaibDgcmXaoscnzcnAcnBcnCcnDcnEaaqcnFcnDcnGciCcnHcnIaaicmXaaiaaaafacnJcnKcnLaaiaaaaaaaaaaaacnMaaaaaaaaaaaaaaaaaaaaaaaacnMaaaaaaaaicnNcnOcnPcnQcnRcnScnTaaqcnUcnVcnWacFcnXaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaabcgWcnYcgWaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuacuacuakqakqacuakqakqakqakUakqakqakqakUcnZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacbWcoacobcoccodcoecofcogcohcoicojcokcolcojcomconcoocoocopaaqcoqcorcoscotbTWcoucovcowcoxcoycozcoycoAcoBcoCcoDcoEcoFaaiaaicmXaosaaiaaicoGaaiaaiabmccIachachachcoHachbgDachcoIaaiaaaafacoJcnKcoKaaicoLcoMcoMcoNaaiaaiboracFacFcoOacFacFcoOatEaaaaaaaaicoPcoQcoPcoRcoScoTcoUaaqaaJcoVaaJaaiaaiaaaaaaaaaaabaabaaaaagaaaaaaaaaaaaaabaaacoWaaaaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaaaaaaaacuaaaaaaaabaabaaaaabaabaaaaaaaabaabaabaaacnZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaEFcoacoYcoZcpacpbcpccpccpccpccpdcpecpfcoocpgcoocoocphcoocpicpjcpkcplcotbTWcpmaaqcpncoxcpocppcpqcoxcprcpscptcpucpvcpwcpxcpycpzcpAcpAcpBcpCcpDcpEcpFbXlbXlbXlcpGbDgbDgbVPbDgaaiaaaafacpHcnKcpIcmScpJcpKcpLcpMcpNcpOcpPcpNcpOcpQcpNcpRcpSabmaaaaaaaaicoPcoPcoPcpTcpUcnScpVcpWcpXcpYcpZcqaaaiaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaabaaacqbaaaaabaabaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaaaaacuaaacqccqdcqeaaacqccqdcqeaaacqccqdcqeaabcqfaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaEFcoacoYcqgcoocphcqhcoocoocoocqicoocqgcqgcoocoocoocoocqjcqkcpjcqlclncqmbTWaaqaaqcqncoxcqocqpcqqcoxcqrclCcqscqtcqucqvccJbVQbDgcqwbVQcqwbDgbDgbDgcmXbDgaaiaoHaoIaoIaoIaoJaaiaaiaaacqxcqycqzcqAcqBcqCchwchwcqDcqEcqFcqGcqEcqFcqGcqEcqFcqGabmaaaaabaaiaaqaaqaaqaaqcqHcoTcqIcqJcqKcqLcqMcqNaaiaaaaaaaaaaaaaaacqOcqOcqOcnZaabaabaabaabcqPaabaabaabaabaabakUcqOcqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaacuaaacqccqQcqeaaacqccqQcqeaaacqccqQcqeaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaEFcoabQUcqgcqRcoocqScqTcqUcqUcpgcoocqgcqVcoocoocoocoocqWcqXcqYcqZbSCcracrbcrccrdcrecoxcqocrfcrgcoxcrhclCaaiauiacFcricoOabtaaicrjabmcrkaaiaaiaaiafaaaiaaiaaaaaaaaaaaaaaaaaaaabaaaafacrlcnKcrmaoscrnchwchwcqDcrocrpcrqcrrcrpcrqcrrcrpcrsabmaabaabaaicnNcnOcnPcrtcrucnScrvcrwcrxcrycrzcrAaaiaaaaaaaaaaaaaaacqOaaaaabaaaaabaaaaaaaaacrBaaaaabaabaaaaaaaaaaaacqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaagaaaaaaaaaakqaabcqccqQcqeaaacqccqQcqeaabcqccqQcqeaabaaaaaaaabaaaaaaaaaaabaaaaaaaaaaaaaaaaabaaaaaacgWcoaaaqcrCcoocrDcrEcrFcrGcrHcrGcrIcrGcrJcrKcojcrLcqgcqgcqkcrMcrNcrOcrPcrQcrRcrScrTcrUcrVcrWcrXcrYcrZclCcsacsbcsccsdcsecsfcsgcshcsicsjcskcslcsmcsncsoaabaaaaaaaaaaaaaaaaaaaabaabcqxcspcsqcsrcsscstchwchwchwcsuchwchwchwchwchwchwchwcsvcswaaaaaaaaicoPcoPcoPcsxcoScoTcsycszcsAcsBcsCcsDaaiaaiaaiaaiaaaaaacqOaaacsEcsEcsEcsEcsEaabcsFaabcsEcsEcsEcsEcsEaaacqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaaabaaacqccqQcqeaabcqccqQcqeaaacqccqQcqeaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaabaaaaabaabaaaaaaaaicsGaaqcsHcsIcsIcsJaaqaaqaaqaaqaaqaaqaaqaaqaaqaaqaaqaaqaaqaaqcsKaaqaaJaaqaaicsLcsMcsNcsOcsPcsQcsRcsSclCcsTcsbcsccsUcsVcsWcsXcsYcsZctactbctcctdctectfaabctgctgctgctgctgaaaaaaaabafacthcnKctictjctkctlchwchwctmchwchwchwchwchwctnchwctoctpaaaaaaaaicoPcoPcoPcrtctqcnSctrctscttctuctvctwctxctyctzaaiaaaaaacqOaabctActBctBctBctBctCctDctEctFctFctFctFctGaabcqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaacuacuakqaabaaacqccqQcqeaabcqccqQcqeaaacqccqQcqeaabaaaaaaaaaaaaaaaaaaaaaaaaaabcbWaaiaaiaaiaaiaaiaaicoaaaqctHctIctIctJabJctKctLctLctLctLctMctNctOctNctNctPctPctNctQbEgccJaaiaaictRctSctTctUctVctWctWctXcfUctYctZcuacubcsVcuccsXcudcuecufcugcuhcuicujcukculcumcuncuocupctgaaaaaacuqafaaaqcuralYaaqcuscutcuucuvabJcuwcuxcuycuzcuAcuBcuCcuDabmaaaaaaaaiaaqaaqaaqaaqcuEcoTcsycuFcuGcuHcsCcoTcuIcoTcuJaaiaaaaaacqOaabcuKcuKcuKcuKcuKaaacsFaaacuKcuKcuKcuKcuKaabcqOaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaacuaaaaabaaaaabaabcuLaabaabaabcuLaabaaaaabcuLaabaaaaaaaaaaaaaaaaaaaaaaaabNtaoIaFOcuMcuNcuOcuPcuQcuRcuSaaqaaqcuTcuUaaqaaqcuVaaiaaiaaiaaiavfaaiafaaaiaaiaaiaaiaaiabmafacuWcuXcuYctWcuZctTctWctWctWctWcvaclCcvbcvccubcubcsVcuccvdcudcuecvecvfcvgcvhcvicvjaabcvkcvlcupcvmctgaaaaaaaaaafacvncvocvpaaqcvqcvrcvscvtaaqcqGcqFcvucvvcvwcvxcqGcqFabmaaaaaaaaicnNcnOcnPcvycrucnScvzcvAcvBcvCcvDcvEcvFcvGcvHaaiaabaabcqOaaaaabaaaaabaabaabaaacsFaaaaabaaaaabaaaaabaaacqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaakqaabcvIcvJcvJcvKcvLcvMcvMcvMcvLcvMcvMcvMcvLcvMcvMcvNcvJcvJcvJcvJcvJcvOcvPcvQcvRcvScvTcvUcvVcvWbYrcoacvXaaqaaqaaqaaqcvYcuVaaicvZcwacwbcwccwdcwecwfcwgcwhcwicwjcwkcwlcwmcwncwocwpcwqctTcwrctWctWctWcwsclCcwtcwucubcwvcwwcwxcwycwzcwAcwBcwCcwDcwEcwFcukcwGcumcwHcupcupctgaaaaaaaabafacwIcvocwJaaqcwKcwLctlcwMaaqcwNcwOcvucwPcwQcvxcwNcwRabmaaaaaaaaicoPcoQcoPcwScoScoTcwTcvAcwUcwVcoTcwWaaqaaqaaqaaiaaaaaacqOaaacsEcsEcsEcsEcsEaabcsFaabcsEcsEcsEcsEcsEaabcqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaacuaaaaabaaaaabaabcwXaabaaaaabcwXaabaaaaabcwXaabaaaaaaaaaaaaaaaaaaaaaaaabNtaoIaXjcwYcwZcxaaaicxbbYrcxccuRcuRcuRcuRcxdcuRcvWaaicxecxfcxgcxhcxicxjcxkcxlcxmcxncxocxpcxqcxrcxscxtcxuctSctTcxvcxwctWctWcxxclCcxycxzcubcxAcsVcxBaaqcxCcxDcxEcxFcxGcxHcxGcxIaabctgctgctgctgctgaabaabaabcqxcxJcvocwJaaqcxKcxLcxMcxNcxOabsabZabZcxPabZcxQaAtaaqabmaaaaaaaaicoPcoPcoPcvycxRcxScxTcqMcxUctwctwctwcxVcxWcxXcxYaaaaaacqOaabctActBctBctBctBctCctDctEctFctFctFctFcxZaabcqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaacuacuakqaabaabcqccyacqeaaacqccyacqeaaacqccyacqeaabaaaaaaaaaaaaaaaaaaaaaaabaabcgWaaiaaiaaiaaiaaqcfHcybbYrcycbYrbYrcuVcydbYraaicyecyfcygcyhcyicyjcykcylcymcyncyocypcyqcyrcyscytcyucyvcywcyxcyycyzcyAcyBcyCcyDcwxcyEcyFcyGcyHcyIcyJcyKcyLcyMcyNcyOcyPcukculcumcyQcyRcyRctgaaaaaaaabafacyScvocyTaaqcyUcyVcyVcyWaaqcyXcyYcyZczaczbczcczdczacswaaacuqaaiaaiaaiaaiaaiczecoTczfcnSczgcnSczhcnSczicnSczjczkaaaaaacqOaabcuKcuKcuKcuKcuKaaacsFaabcuKcuKcuKcuKcuKaaacqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaaaaaaacqccyacqeaabcqccyacqeaaacqccyacqeaaaaaaaaaaabaaaaaaaaaaaaaabaabaabaaaaaaaabaabczlczlczlczlczlczlczlczmczlczlaaicznczocxgcxgczpczqczrczscztaaiczuczvcwmczwczxaaiczyctWczzczAczBczCcyAczDczEczFczGczHczIczJczGczKczLczMczNcubczOczPczQcvjaabcvkczRczSczTctgaaaaaaaaaafaaaqczUaosaaqczVczWczXczYczZcvocAacAbczacAccAdcAecAfcAgaabaaaaaaaaaaaaaaaaaicAhcAicAjcAkcAlcAmcAncAocAlcAmcApaaiaaaaabcnZaaaaabaaaaabaaaaabaaacAqaaaaabaaaaabaabaabaabcqOaaaaaaaaaaaaaaaaaaaaaaaacAraaaaaaaaacAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMIaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaakqaabcqccyacqeaaacqccyacqeaaacqccyacqeaabaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaabaabaabczlcAscAscAtcAucAvcAvcAwcAxcAycAzcygcyhcxgcxgcxgcAAcxgcxgcxgaaicABcACcADcAEcAFcAGaoacAHcAIcAJcAKcALcdjbXicAMcANcAOcAPcxAcsVcAQcARcAScATcAUcubczOcAVcAWcAXcAYcumcAZcyRcyRctgaabaaaaaacqxcBacBbcBccBdcBecBfcBecBecBgcBhcBicBjcBjcBkcBlcBmcBncBoaabaabaaaaaaaaaaaaaaicBpcBqcBraaqcBscBtcBuaaqcBvcBwcBxaaiaaaaaacqOaaacsEcsEcsEcsEcsEaabcqPaabcsEcsEcsEcsEcsEaabcqOaaaaaaaaaaaaaaaaaaaaaaaacArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaakqaabcqccyacqeaaacqccyacqeaabcqccyacqeaabaabaabaaaaabaaaaaaaabaabaaaaaaaaaaabaaaaaaczlcAscAscAtcBycBycBycBzcBzcBAaaicBBcBCcBDcBEcBFcBGcBHcBIcBIcBIcBJcBKcxgcxgcxgcBLcBMcBNaaqcBOcBPcBQcBRcBSaaiaaiaaicBTcxAcsVcBUcBVcBWcBXcBYcubcBZcCacCbcCccCdctgctgctgctgctgaaaaaaaaaafacCecCfcCgcChcCicCjcCicCicCkcClcCmcCncBncCocCpcAeczacCqaabaabaaaaaaaaaaaaaaicCrcoPcoPaaqcCscoPcoPaaqcCscoPcoPaaiaaaaaacqOaabctActBctBctBctBcCtcCucCtctFctFctFctFcxZaabcqOaaacAraaaaaacAraaaaaacArcArcArcArcArcArcAraaaaaacAraaaaaacAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaakUaabcqccCvcqeaaacqccCvcqeaaacqccCvcqeaabakqaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaabczlcCwcCxcBycBycBycCyaaiaaibXiaaiaaiaaiaaicCzcCAcCBcCCcCDcCDcCDcCEcCFcCGcCDcCDcCDcCFcCHcCIcCJcBPcCKcCLcBScCMcCNacFcCOcCPcCQcCRcCScAUcCTcCUcCVcCWcCXcCYcukcCZcumcDacDbcDbctgaaaaaaaaaafacDccDdcDecDfcDgcDhcDiczacDjcDkcDlcDmcDncDocDpcDqcDrcDsaaaaaaaaaaaaaaaaaaaaicDtcoPcoPaaqcDucoPcoPaaqcDucoPcoPaaiaaaaaacqOaabcuKcuKcuKcuKcuKaaacqPaaacuKcuKcuKcuKcuKaaacqOaaacArcArcArcAraaacArcArcArcArcArcArcArcArcAraaacArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaakqaaaaabaaaaaaaaaaabaabaabaaaaaaaabaabaaaakqaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaabczlcBycBycBycBycBycByaaicDvcDwcDxcDycDzaaicDAcDBcDCczocxgcxgcDDcDEcDFcDGcDHcDIcDJcDKaaicDLcCJcBPcDMcDNcBSaaicDOaaicDPcDQcubcCRcCScDRcubcCUcCVczOczPcDScvjcDTcvkcDUcDVcDWctgaaaaaaaaabgCcDXcDYcDYcDZachachbgEcEacEbcEccEdcEccEeaaiaaiabmavfaaiaaaaaaaaaaaaaaaaaaaaicoPcoPcoPaaqcEfcoPcoPaaqcEfcoPcoPaaiaaaaabcqOaaaaaaaabaabaabaaaaaacqPaabaaaaaaaabaabaaaaaacqOaaacArcArcArcAraaacArcArcArcArcArcArcArcArcAraaacArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaacuacuakqacuacuakUakqakqakqakqacuakqakqacucEgaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaczlcEhcBzcEicEjcEkcElaaicEmcEncEocEpcEqcErcEscEtcEuczocxgcEvcEwacFcExcEycEzcEAcEBaujcECcDCczocEDcEEaaqcEFaaiabmaaicEGcEHcubcCRcCScAUcubcEIcCVczOcEJcEKcAXcELcumcEMcDbcDbctgaaaaaaaaacENaaaaaaaaaaaaaaaaaaafacEOczaczacEPcEQcERaaiaaccEScETcEUaaaaaaaaaaaaaaaaaaaaiaaiaaiaaiaaiaaiaaiaaiaaicEVcEVcEVaaiaaaaaacqOcqOcqOcqOcqOaaaaaaaaacqPaaaaaaaaacqOcqOcqOcnZcqOaaacArcArcArcAraaacArcArcArcArcArcArcArcArcAraaacArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabczlczlczlcEWcEXcEYcEZaaicFacFbcFccFccFdcFecCDcFfcFgcFhcFicFjcFjcFkcFlcFmcFncFocFpcFkcFqcFrcFscFtcxgcFucFvcFwcDOaaicFxcFycubcCRcubcFzcubcCUcCVczOczPcFAcvjcDTctgctgctgctgctgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafacFBczaczaczYcFCcFDaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacENaaaaaaaaaaaaaaaaaaaaaaaacFEcFEcFEaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaabcFFaabcqOaaaaaaaaaaaaaaaaaaaaacArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabcFGcFHcFIcFJaabaabaaicFKcFLcFccFccFMaaicFNcFOcFPcFQcFRcFScFTaaicFUcFVcFWcxgcFXaaicFYcFZcGacFQcFQcGbcGcaaicGdaaicGecGfcubcCRcubcBUcBVcGgcGhcCWcGicGjcukcGkcumcGlcGmcGmctgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabgCcGncGocGpcGqcGrcGsaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaaaaabaaacqOaaaaaaaaaaaaaaaaaaaaacArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabcFGcGtcGucGvaabaaaaaicGwcFLcFccFccGxaaicGycGzaaicGAcGBcGBcGBaaicGCcGDcGEcGFcGGaaicGBcGBcGBcGAaaicGHcGIaaicDOaaicGJcGKcGLcGMcGNcGOcGPcGQcyNcGRczPcGScvjcDTcvkcGTcGUcGVctgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaicGWcoMcoMcoMcoMcGXaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOcqOcqOcqOcqOaaaaaaaaaaaaaaaaaaaaacArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYaaaaaaaaacGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcFGcGZcHacFGcHbaaaaaicHccHdcFccFccHeaaicHfcHgaaicHhcHicHjcHkaDpcHlcHmcHncHocGGaDpcHicHicHicHpcHqcHrcHsaaicDOcHtcHucHvcHwcGPcHxcHycHzcHAcHBcHCcHDcHEcAXcELcumcHFcGmcGmctgaabaabaaaaaaaaaaaaaaaaaaaaaaaacENaaaaaaaaaaaaaaaaaacENaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacHGcHGcHGcHGcHGcHGcHGaaicHHcFbcFccFccHIaaicCMcHJaaiaaibNtaoIcHKcHLcHMcFQcHNcFQcHOcHPcHKaoIaFRaaiaaicHQcHRaaicDOaaicHScHTcHwcHUctZcubcubcHVczKcHUczPcHWcvjcDTctgctgctgctgctgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYaaaaaacGYaaaaaacGYcGYcGYcGYcGYcGYcGYaaaaaacGYaaaaaacGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacHGcHGcHGcHGcHGcHGcHGaaicHXcHYcFccFccHZaaiaaicIaaaicIbcIccIccIdcIecIfcIfcIfcIfcIfcIecIgcIccIccIhaaicIiaaiaaicDOaaicIjcGLcIkcIlcImcIncIocIlcIocIlcIpcGPcIqcDTaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYaaacGYcGYcGYcGYcGYcGYcGYcGYcGYaaacGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacHGcHGcHGcHGcHGcHGcHGaaicIrcIscFccFccItaaicIucIvcIwcIxaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaabaaaaaacIycIzcIAcIBaaicICacFcIDcIEcIFcIGcIHcIIcIJcIKcubcILcIMcINcIOcDTaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacArcArcArcAraaaaaacArcArcArcArcArcArcAraaaaaacArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYaaacGYcGYcGYcGYcGYcGYcGYcGYcGYaaacGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacHGcHGcHGcHGcHGcHGcHGaaicHHcFbcFccFccIPaaicIQcIRcIRaaaaaaaabaabaabaabaabaabaabaabaabaabaabaaaaaacIRcIRcIQaaicCMaaicIScITcIUcIVcIWcIXcIYcIVcIYcIZcIYcIZcJacDTaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaacArcArcArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYaaacGYcGYcGYcGYcGYcGYcGYcGYcGYaaacGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacHGcHGcHGcHGcHGcHGcHGaaicJccJdcFccFccJeaaicJfcJgcIRaabaabaabcJhaaaaaaaaaaaacJhaaaaaacJhaabaabaabcIRcJicJjaaicCMaaiaabcJkaabcJlcJmcJncJocJpcJocJqcJocJqcJrcJsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacArcArcArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaicJtcJdcFccFccIPaaicJucIRcJvaaaaaaaabaaaaaaaaaaaaaaacJwaaaaaaaaaaabaaaaaacIRcIRcJuaaicCMaaictgcJxcvkcJxctgcJxcvkcJxctgcJycvkcJzctgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacArcArcArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaicJAcFbcFccFccJBaaicJCcJDcIRaaaaaaaabaaaaaaaabaabaabaabaabaaaaaaaabaaaaaacIRcJEcJFaaicJGaaictgcJHcJIcJJctgcJKcJLcJMctgcJNcJOcJPctgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacArcArcArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaiaaiaaiaaiaaiaaiaaiaaicIQcIRaaaaaaaabcJhaabaabaacaacaacaabcJQaaaaabaaaaaacIRcIQaaiaaicCMaaictgcJRcJScJRctgcJTcJUcJTctgcJVcJWcJVctgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacArcArcArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaacaabaacaacaabaabaabacuacuaaiaaicJXcIRaaaaaaaabaaaaaaaabcJYcJZaacaabaaaaaaaabaaaaaacIRcKaaaiaaicCMaaictgcJRcKbcJRctgcJTcKccJTctgcJVcKdcJVctgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaabaabaaaaaaaabaabacuaaiaaicIQcIRaaaaaaaabaaacKeaabaacaacaacaabaabcJhaabaaaaaacIRcIQaaiaaicCMaaictgctgctgctgctgctgctgctgctgctgctgctgctgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaicJEcJFcIRaaaaaaaabaaaaaaaabaabaabaabaabaaaaaaaabaaaaaacIRcJCcJDaaicJGaaiaaiaaiaaiaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaacGYcGYcGYcGYaaaaaacGYcGYcGYcGYcGYcGYcGYaaaaaacGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaabaaicJucIRcKgaaaaaacKhaaaaaaaaaaabaaaaaaaaaaaaaaaaabaaaaaacIRcIRcJuaaicCMaiVcKicKjcKkcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaicKncKocIRaabaabaabcJhaaaaaacJhaaaaaaaaaaaacJhaabcKpaabcIRcKqcKraaicCMcKscxgcxgcKtcKuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaicKvcKwcKxaaaaaaaabaabaabaabaabaabaabaabaabaabaabaaaaaacKycKwcKzaaicCMaaicKAcKBcKtcKCaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacDEaaicdjcIycKxaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaabaaaaaacKycIxcdjaaiaaicCMaaiaaiaaicKDaaiaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaiaaicIycIccIccIccIccIccIccIccIccIccIccIccIccIccIxaaiaaiaaiaaicJGaaiaaaaabcKEcKFaabaaaaaaaaaaabaaaaaaaaaaabaaaaaaaaaaabaaaaaaaaaaabaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaiaaaaaiaaicKGaaiaabaabcKHcKIcKJcKKcKKcKKcKJcKKcKKcKKcKJcKKcKKcKKcKJcKKcKKcKLcKMaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaaicKNaaiaaiaaiaaiaaaaabaaaaaaaaaaabaaaaaaaaaaabaaaaaaaaaaabaaaaaacKHcKOcKFaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaicCMcCMcKPcKQcKQcKRaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabcKScKOcKMaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaicJGcCMcKTcKUcKVcKWaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaacKHcKOcKFaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaicKXcCMcKYcKQcKQcKZaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaacKScLacKFaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacDEaaiaaiaaiaaiaaiaaiaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaabcKScLbaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaabaaqcLcaaqcLdcLeaaiaaiaaiaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaaqcLfcLgcLhcLiachcLjcLkaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaabaaqcLfcLlcLmcLmcLncLocLpaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaabaaqcLqcLrcLmcLmcLscLtcLuaaiaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaaqaaqaaJcLmcLmaaiabmaaiaaiaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaaaaabaaaakUaaaaaaaaaaaaaaaaaaaaaaaaakqalGansantanualGalKanvanwanxanyanzanAanBanCanDanDanEanFanGanHanIanJanKanLanManNanOanPanNanQanRanKanSanTanUanKanKanUanOanTanUanKanKanSanTanManVanWanXanYanZautaobaocaoGannaodamlamlaoeaaaaofaogaofaaaaaaaaaahxahxahxaaaaaaaaaaaaaaaaaaaaaakqaabaohaohaohaohaohaabaoiaabaohaohaohaohaohaabakqaaaaaaajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakqaabaojaabakqaaaaaaaaaaaaaaaaaaaaaaaaakqalGaokaokaolalGaaaaaaaaaavLavfaonaooaopaxdaxdaxdaxoaxoaxoaxoaoqaoraxEaxEaxEaxQaotaouaxQaxEaxEaxEaovaowaxUaxSaxVaxUaozaowatsatsatsaoAaoBatsaxXaoCaoDaoEaoFazrazRaocaoGasnasnasnaATaAtaBaasnaoKasnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakqaabaoLaoMaoMaoMaoMaoNaoOaoPaoQaoQaoQaoQaoRaabakqaaaaaaajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaacuacuacuakqakqaaaaaaaaaaoSaaaaaaaaaakqakqacuacuacuaaaaaaakUamoaoTaokaoUalGalKaoVanwaoWaoXaoYaoZapaapbapcapdaxoapeapfapgaphapiapjapkaplapmapnapoappapqaprapjapsaptaDpaBbaEFaEmapyaptatsapzapAapBapCatsapDapEapFapGapHapIazRaocapJaFOapLapMapNapNapOasnapPasnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakqaabapQapQapQapQapQaabapRaabapQapQapQapQapQaabakqaaaaaaajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaacuaaaaaaaabaabaaaaaaaaaaoSaabaabaaaaabaabaaaaaaacuaaaaaaakqalGapSaokaokapTapUapVapWapXapYamDapZaqaamyamyaqbaxoaqcaqdaqeaqfaqgaqhaqiaqjaqkaqlaqmaqnaqjaqoaqpaqqaqraFRaFQaJwaJkaqwaqxaKxaqzaqAaqBaqCatsaqDaqEaqEaqFaqEaqGazRaocannannannannaqHannaqIaqJaqKasnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaaaaaaaaaaabaaaaaaaabapRaaaaaaaaaaabaaaaaaaaaacuaaaaaaajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaacuaabaqLaqLaqLaqLaqLaabaqMaabaqLaqLaqLaqLaqLaabacuaaaaaaakqalGaqNaqNaqNalGalKalLalLaqOaqPaqQanDaqRaqSamyaqTaxoaqUaqVaqWaqXaqYaqZaraarbarcardarearfargarhaqZariaqxaMgaKMaMhaMgaqwaqxatsarmarnaroarpatsarqarraqEaqFaqEarsazRartaruarvarwarvarxaryasnasnaoGasnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakqaabaohaohaohaohaohaabapRaabaohaohaohaohaohaabakqaaaajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagragragragragragragragragraaaaaaaaaaaaaaaacuaabarzarAarAarAarAarBarCarDarEarEarEarEarFaabacuaaaaaaakqarGarHarHarHarIarJaaaaaaavfavfavfavfavfarKamyarLaMsaxoaxoaxoarMarNaxEaxEaxEaxEarOarPaxEaxEaxEaNlarQarRaNxaNtaNEaNCaqwarWatsarXarYarZasaaNPasbascasdaseaqEasfazRasgashasiasjaskaslasmaOcasoaspasnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakqaabaoLaoMaoMaoMaoMaoNaoOaoPaoQaoQaoQaoQaoRaabakqaaaajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaabasqasqasqasqasqaabasraabasqasqasqasqasqaabacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavfassamyarLaMsastapfapgaphapiapjasuaplasvaswasxasyaszasAapjasBasCasDasEasFasFasGasHatsasIasJasKasLatsasMasNasOaqFaqEasPazRasgaqHashashashasQannasRasSasTasnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakqaabapQapQapQapQapQaabapRaabapQapQapQapQapQaabakqaaaaaaajFajFajFajFaaaaaaajFajFajFajFajFajFajFaaaaaaajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaaaaaaaaaaabaaaaaaaabasraaaaaaaaaaabaaaaaaaaaacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavfasUamyasVaMsaqcasWasXasYasZataatbatcatdateatfatgathatiatjatkatlatlatmatlatlatnatoaPdatqatratsattatsatuatvatwatxatyatzazRasgatAatBatBatBatCatDaPeatFatGasnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatHaaaaaaaaaaabaaaaaaaaaapRaaaaaaaaaaabaaaaaaaaaacuaaaaaaaaaaaaaaaaaaaaaaaaajFajFajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaabaqLaqLaqLaqLaqLaabasraabaqLaqLaqLaqLaqLaabacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavfatIamyatJaMsaqUatKatLatMatNaqZaraatOatPatQatRatPatSarhaqZatTatUatVatUatUatVatUatWatsarXatXatsatYatsatZauaaubaucaudaudaueaufaPsaPlaPlaPlaPuaPtaQpaPCaPCaPCaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaakqaabaohaohaohaohaohaabapRaabaohaohaohaohaohaabakqaaaaaaaaaaaaaaaaaaaaaaaaajFajFajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaabarzarAarAarAarAarBarCarDarEarEarEarEarFaabacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaQBaQBaQBaQBaQBaQBavfavfauhavfaMsaMsaMsaQCaRiaQDaUHaUHaWYaUHaWYaUHaUHaWZaNlaNlaukaulaumaunaulaumaunauoaXaaXaaXaaXaaXaatsaupauqauraurausauraXbauuaPlauvauwauxaPuauyauzauAauBaPtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaabaoLaoMaoMaoMaoMaoNaoOaoPaoQaoQaoQaoQaoRaabakqaaaaaaaaaaaaaaaaaaaaaaaaajFajFajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaabasqasqasqasqasqaabasraabasqasqasqasqasqaabacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaQBauCauDauEauFauGauHauIauJauIauKauIauIauLauMauMauMauMauMauNauOauPauMauMauMauMauQauMauMauMauMauRauSauTauUauVauWauXauYazrauZavaavbavcavdaveaXcavgaPlavhaviavjaPuavkavlavkavmaPtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaaaapQapQapQapQapQaabapRaabapQapQapQapQapQaaaakUaaaaaaaaaaaaaaaaaaaaaaaaajFajFajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatHaaaaaaaaaaabaaaaaaaaaasraaaaaaaaaaabaaaaaaaabacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaQBavnavoavpavqavqavravsavtavuauRauRauRavvauRauRauRauRauRavwauRauRauRauRauRauRavxauRauRauRauRavyauRavzauRavAauRauRavBazravCavDavEavFavbavGaXcavHaPlavIavJavKaXdavMavNavOauBaPtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaaaaabaaaaaaaaaaaaaabapRaaaaaaaaaaaaaaaaabaaaakqaaaaaaaaaaaaaaaaaaaaaaaaajFajFajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaabaqLaqLaqLaqLaqLaabasraabaqLaqLaqLaqLaqLaabacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaQBavPavQavRavSavTaQBavUavVavWavXavYavZawaawbavVavXavXavXawcavXavXavXavXavXavXawdaweawfawfawfawgawhawiawhawjawkawhawlazraXeaXeaXeaXeaXeaXeaXcavgaPlawmaviawnaPuavkawoavkavmaPtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuacuakqaaaaaaaaaaabaabapRaabaaaaaaaaaaaaakqakqakqaaaaaaaaaaaaaaaaaaaaaaaaaaaajFajFajFajFajFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaofawpaofaaaaaaaaaaaaaaaaaaaaaacuaabarzarAarAarAarAarBarCarDarEarEarEarEarFaaaacuaaaaaaaaaaaaaabaaaaaaaaaaaaaQBaQBaQBaQBaQBaQBaQBaXfaXfaXgawqawrawsaXhawtaXiawuawvaXiawwaXiaXjaXjaXjaXjaXjaXjawxaXjaXjawyawzawAaXyaXfaXzaXfawBaXfaXfapMannannannannannawCavgaPlawDaviawEaPuawFavNavOauBaPtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabawHawIawHaaaaaaaaaaaaaaaaaaaaaacuaabasqasqasqasqasqaabawJaabasqasqasqasqasqaabacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaXgawKawLawMaXhawNaXiawOawPawQawRawSawTawUawVawWawXawYawZaxaaxbaxcauRauSaYOaxeaxfaxgaxgaxgaxgaxgaxhaxgaxgaxgaxgaxiaxjaxkaxlaxmaxnbaJaxpaxqavkavmaPtaaaaaaaaaaaaaaaaaaaabaxraxsaxsaxsaxsaxsaxtaabaaaaaaaaaaaaaaaaaaaxuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxvaxwaxxaaaaxyaxzaxAaaaaabaxBaxCaxBaaaaaaaaaaaaaaaaaaaaaacuaaaaabaabaabaabaabaaaaxDaaaaaaaaaaaaaaaaaaaabacuaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbkaxFaxGaxHaXhawNaXiaxIaxJaxKawRaxLaxMaxNaxNaxNaxNaxNawZaxNaxOauMauRauSaXfaxPbbIbbXbbXbbXbbXaxRbckbgwbgwbgwbgwbgwbgwbgDbgCaxTbgEbjxbgJaxWbjzaPtaPtbjEbjEbjEbjEbjEbjEbjEaxYaxZaxZaxZaxZaxZaxYbjIaaaaaaaaaaaaaaaaaaaxuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayaaybaycaybayaaydayeaydayaaabaxBayfaygaaaaaaaaaaaaaaaaaaaaaacuacuacuacuaaaaaaaaaaaaaxDaaaaaaaaaaaaaaaaaaaaaacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaabaabaabbkkayhayiaxHaXhawNaXiayjaykaylawRaymaxNaxNaynaxNayoayoawZaxNaxOauMauRaypaXfayqbbIayraysaytblQayuayvaywayxayyayzayAayBayCayDayEayFayGayHayIayJayKayLayMayNayOayPayQayRbjEaxYaxZaxZaxZaxZaxZaxYbjIaabaaaaaaaaaaaaaaaaxuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaySaybayTaybaySaydayUaydaySayVayWayXayYayZayZazaayVayVaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaxDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazbazbazbazbazbazbazbazbazbaabbkkazcazdazebmKazfbmWazgazhaziazjawSazkaxNazlazmaznazoazpazqaxOauMauRauSaXfasgborazsaysaytblQaztayRayRayRayRayRayRayRayRayRayRazuazvazwazxazyazzazAazBazBazBazBazCazBazDazEaxZaxZaxZaxZaxZazEbjIbjIbjIaaaaaaaaaaaaaxuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaySazFazGazHaySazIazJazKaySaxCaxCazLazMazNazOazPazQayVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaboBazSazTazUazVazWazXazYazbaabbkkazZaAaaAbbkkaAcaXiaAdaAeaAfaAgaAhaznaAiaAjaAkaAlaAmaAnaAoaApaAqavtaArboCaAsbpMaAuaysaytblQaAvayRayRaAwaAwaAwayRayRayRayRaAxaAyaAzaAAaABaACaADaAEaAFaAGaAFaAFaAHaAFaAIaAJaxZaxZaxZaxZaxZaAKaALaAMaANaaaaaaaaaaaaaxuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaySaAOaAPaAQaySaAOaAPaAQaySaARaASaASaxCaxCaxCaASaASawHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeHCaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaabaabaaaaaaaabbqmazSaAUaAVaAWaAXaAYaAYazbazbbkkbbkbqpbqpbqpaAZbrwbttbrwbrwbrwbwsbtDbtDbwObtDbtDbtDbtDbyhbwTaBcauRaBdaXfasgbyiaHvaysaytblQaztayRaAwaBfaBfaBgaAwayRaBhayRaBiaBjaBkaBlaBmaBnaBoaBpaBnaBqaBnaBnaBraBhaBsaANaxZaxZaxZaxZaxZaANaBtaBuaBvaaaaaaaaaaaaaxuaaaaaaaaaaaaaaaaaaaaabykbykaBwaBxaBxaBxaBxaBybykbykaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayaaySaBzaBAayaaySaBBaBAayaaySaBCaySaySaySaySaySaASaxBaaaaaaaaaaaaaaaaaaaaaaabaaaaBDaBEaBDaabaabaabaabaaaaaaaaaaabazbazbazbazbaBFaBGaBGaBHazbazbazbazbaBIaAYaAYazbaBJaBKaBLaBMaBMaBNaBOaBPaBQaBQaBQaBQaBRaBQaBSaBTaBUaBQaBQaBVaBVaBWaBXaBYaBZbywaCabyiaCbaBeaBeblQaztayRaAwaCcaCdaCeaAwayRayRaCfaCgaBjaChaCiayRayRaCjaCkayRaClayRayRaCmayRaCnaCoaxZaxZaxZaxZaxZaCoaCpaBuaBvaaaaaaaaaaaaaCqaaaaaaaaaaaaaaaaaabykbykaCraCsaCtaCuaCvaCwaCxaCtbykbykaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCyaCzaCAaCzaCBaCzaCCaCzaCDaCEaCFaCFaCFaCFaCGaySaCHaxBaaaaabaabaaaaaaaaaaaaaabaaaaCIaCJaCKaabaaaaabaaaaaaaaaaaaaaaazbaCLaCMaCNaCMaCMaCMaCMaCOaCMaCMaCPaCQaCNaCRaCSaCSaCSaCSaCSaCSaCSaCTbyxbyxbyxbyxbyBbyHbyxaCUbyxbyIbyBbyxbyxbyxbyxaCVaCWaCXaCYaCZbpMaDaaDbaBeaDcaztayRaAwaDdaBfaBfaAwayRayRayRaDeaDfaDgaDhayRayRaCjaDiayRayRayRayRaDjayRaDkaDlaxZaxZaxZaxZaxZaDmaDnaDoaCoaaaaaaaaabzQaDqbzQaaaaaaaaabykbykbykaDraCuaDsaCuaDtaDuaCuaCuaCuaDvbykaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDwaDxaDyaDzaDAaDBaDCaDDaDEaDCaDFaDGaDCaDCaDHaySaxCayWaabaabaaaaaaaaaaaaaaaaabaDIaDJaDKaDLaDMaaaaabaaaaaaaaaaaaaaaazbaDNazbaDOaDPaDQaDQaDQaDRaDQaDQaDQaDSaDOaDTaDUaDUaDUaDUaDUaDUaDUaAYbyxaDVaDWaDXaDYaDZaEaaEbaEcaEdaEeaEfaDWaEgbyxaEhauRaEiaXfaEjbyiaEkaElaElbAQaEnaEoaEpaEqaEqaEraEsaBnaEtaEsaEsaEuaEvaEwayRayRaExaEyaEzaEAaEAaEAaEBayRaECaEDaxZaxZaxZaxZaxZaEEbjIbjIbjIaaaaaaaaabBlaEGbBlaaaaaabykbykaEHbykaEIaEJaEKaELaCuaCuaEMaENaCuaEObykaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaySaEPaEQaEPaERaDyaDyaESaEPaEQaEPaETaEUaEVaEWaySaxCayVayVaEXayZayZayZayZazaayVaEYaEZaFaaFbaEYazbazbaFcaFdaFeazbazbazbaDNaFfaDOaaaaabaaaaabaaaaabaaaaabaaaaDOaDTaDUaFgaFhaFiaFjaFkaDUaAYbyxaFlaFlaFmaFnaFoaFpaFqaFpaFraFsaFtaFlaFlbyxaEhauRaFuaXfaEjbyiaHvaysaytblQaztaFvaFwaFxaFyaFzaFzaFAaFBaFzaFBaFCaFDaFEaFFaFGaFHaFIaFJaFKaFKaFKaFLayRbjEaFMaxZaxZaxZaxZaxZaFNbjIaabaaaaaaaaabBVbBYaFPbCabBZaaabykaFSaFTaFUaFVaFWaFXaCuaCuaCuaFYaFZaCuaGabykaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaabaGbayaaGcaAPaGdaGeaGfaGgaGhaGdaAPaGiaGjayaaGkaGlaySaxCaxCaxCaxCaxCaxCaxCaxCaGmaGnaEYaGoaGpaGqaEYaGraGsaCMaCMaCMaCMaCMaGtaGuaGvaDOaabaGwaGwaGwaGwaGwaGwaGwaabaDOaDTaDUaGxaGyaGzaGAaGxaDUaAYbyxbyxbyxbyxaGBaGCaDWaGDaDWaGCaGEbyxbyxbyxbyxaEhauRaGFaXfaEjbyiaAuaysaytblQaAvaGGbCtbCtbCtbCtbCtbCtbCtaGHbCtaPjaPjaPjaPjaPjaGIbjEaGJaGKaGLaGMaGNbjEbjEaFMaxZaxZaxZaxZaxZaFNbjIaaaaaaaaaaaabDKaGOaGPaGQbDKaaabykaGRaGSbykaGTaGUaGVaGWaGXaGYaGZaHaaDtbykbEgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDwaEQaHbaHcaHcaHcaHcaHdaEQaDwaHeayaaHfaHgaHhaHhaHhaHhaHhaHhaHhaHhaxCaHiaHjaEYaHkaHlaHmaHpaHnaHoaHnaHnaHnaHnaHnaHnaHnaHnaHpaaaaGwaHqaHraHsaHtaHuaGwaaaaDOaDTaDUaGxaHwaHEaHxaGxaDUaAYbyxaHyaHyaFmaHzaHAaFpaFqaFpaHAaHBaHCaFlaFlbyxaEhauRaEiaXfaHDbbIeHtaysaytblQaztaGGbCtaHFaHGaHHaHHbCtaHIaHGaHJaPjaHKaHLaHMaPjaHNbjEaHOaHPaHPaHPaHQbjEaabaHRaHSaHSaHSaHSaHSaHTaabaaaaaaaagaaabDKaHUaHVaHWbDKaaabykaHXaHYbykbykbykbykbykaHZbykbykbykbykbykbykaJvaJvaJvaJvaJvaJvaJvaJvaJvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaaIbaIcaIbaIbaIdaIeaIbaIbaIcaIfaIgayaaERaIhaHhaIiaIjaIkaIlaImaInaHhaxCaIoayVaEYaEYaIpaIqaHpaIraIsaItaIuaIvaIwaIxaIyaIzaIAaHpaabaGwaIBaICaIDaIEaIFaGwaabaDOaDTaDUaIGaIHaIIaIJaIKaDUaAYbyxaDVaDWaILaIMaGCaDWaINaDWaGCaIOaIPaDWaEgbyxaEhauRaIQaXfaEjborazsaysaytblQaIRaISbCtaITaHGaHGaHGaIUaIVaIWaIXaPjaIYaIZaJaaJbaJcbjEaJdaJeaJfaJeaJgbjEaaaaabaaaaabaaaaabaaaaabaaaaaaaaaaaaaaabDKaJhaJiaJjbDKbEsbykbykbykbykaJlaJmaJnaJnaJoaJnaJpaJnaJqaJraJraJsaJraJraJraJraJtaJuaJvaJvbEDbEFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaaIfaIbaJxaJyaJzaJAaJBaJCaJDaJEaJFaJGaJHaJIaEPaERaJJaHhaJKaJLaJMaJNaJMaJOaJPaxCaJQaJRaJSaJTaJUaJVaJWaJXaJYaJZaJZaJZaKaaJZaJZaKbaKcaHpaaaaGwaKdaICaKeaIEaKfaGwaaaaDOaDTaDUaKgaKhaKiaKjaKkaDUaAYbyxaKlaKlaFmaKmaHAaFpaKnaFpaHAaKoaFtaKpaKpbyxaKqawzaKraXfaEjborbEWbEWbEWbEWaKsaKtaKuaKvaKwbEXbEXbEXbEYbEXbGgbFjaKyaKzaKAbGsaKBbjEbjEbjEbjEbjEbjEbjEbGtbGtbGtaJvaJvaJvaJvbGubGCaJvaJvaJvaJvbDKbDKaKCbGRbDKaKDaKEaKFaKGaKHaKIaKJbGSbGSbGSbGSbGTaKKaKLbHwbHwbHHbHwbHNbHwbHwbHYaKNaOeaOeaKObEFbIgbIgbIgbIgbIgbIgbIgbIgbIgabAacOaaaaaaaaaaaaaaaaaaaaaaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJHaKQaKRaKSaJGaKTaJzaKTaJzaKTaJzaKTaJGaKUaKVaGdaERaKWaHhaKXaKYaKZaLaaLbaLcaHhaLdaLeaLfaLgaLhaLiaLjaHnaLkaJZaJZaJZaJZaJZaJZaJZaKbaLlaHpaabaGwaLmaLnaLoaLpaLqaGwaabaDOaDTaDUaLraLsaLtaLuaLvaDUaAYbyxbyxbyxbyxaLwaGCaDWaGDaDWaGCaLxbyxbyxbyxbyxaLyaLzaLAaXfaHDaLBaLCaLCaLCaLDaLEaADbJdaLFaLGbJdaLHbJdaLIbJdaLJbJuaLKaLLaLMaPjaLNaLOaLPaLQaLQaLOaLRaLSaLSaLSaLSaLSaLTaLUaLSaLVaLWaLXaLYaLZaMaaMaaMbaMcaMdaMdaMdaMeaJuaMfbKWbKDaMibLLaMjaMkaMlbLMbLNaMmbLNaMnaMoaMpaMqaMrbLPaMtaMuaMvaMwaMxbEFaMyaMzaMAaMBaMCaMDaMEaMFaMGaMHaaaaaaaaaaaaaaaaaaaaaaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMIaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMJaJzaJzaIcaJGaKTaJzaKTaMKaKTaJzaKTaJGaKUaKVaGdaERaMLaHhaHhaMMaMNaMOaMNaHhaHhaySaySaySaMPaMQaMRaMSaHnaMTaMUaMVaJZaJZaMWaJZaMXaMYaMZaHpaaaaGwaGwaNaaNbaNaaGwaGwaaaaDOaDTaDUaNcaNdaNeaLuaNfaDUaAYbyxaDVaDWaNgaIMaGCaDWaGDaDWaGCaIOaNhbyxbyxbyxaNiaNjaNkbLQaNmbNlasnasnbNtbNqaNnaNobCtaNpaHGbCtaNqbCtaNrbCtaNsbNuaNuaNvaNwbNQaNyaNzaNAaNBbOsbNRaNDbOsbOsbOxbOsaNzaNFaNzaJsaNzaNzaNGaNHaNIaNJaNJaNKaNLaNMaNNaNJaNOaJrbOAbPdaNQaNRaNSaNTaNUaNVbLMaNWaNXbLNaNYaNZaOaaObaMrbPgaMtaMuaMvaOdaOebEFaOfaOgaOgaOhaMFaMFaMFaMFaMGaMHaaaaaaaaaaaaaaaaaaaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaJHaOiaKRaKSaJGaKTaJzaKTaJzaKTaJzaKTaJGaKUaKVaGdaERaOjaOkaOlaOmaOnaOoaDyaOpaOqaOraOsaOtaOuaOvaOwaOwaHnaOxaOyaOzaOAaOBaOCaODaOEaOFaOGaHpaaaaabaaaaOHaOIaOHaaaaabaaaayaaDTaDUaOJaOKaOLaOMaONaDUaAYbyxaOOaOPaFmaOQaORaFpaOSaFpaOTaOUaOVbyxaOWaOXaOYaOZaPaaPbaPcbPhaaaaaabNtbPSaPfaPgbCtaPhaHGaHGaHGaPiaHGaHGaHGbScaPjaPkaPjbSUbSYaPjaPmaPjbTcaPnaPoaPpaPqaPrbTcbTHbUbbTYbUgbTYbTYbTYbTYbUhbTYbTYbUmbTYbTYbTYbTYaPvaJubLLaPwaNRaPxaPyaPzaPAaPBbUoaPDaPEbLNbDSaPGaPHaPIaPJbPgaMtaMuaMvaPKaPLbEFaPMaOgaOgaOhaMFaMFaMFaMFaMGaMHaaaaaaaaaaaaaaaaaaaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPNaPOaIbaJxaJGaJzaJzaPPaJzaJzaPQaJzaJGaJHaPRaPSaERaPTaPUaPVaPWaPVaPVaPVaPVaPVaPXaDyaySaPYaPYaPYaPYaHnaPZaQaaQbaHnaHnaHnaHnaPZaQcaQdaHpaQfaQgaQgaQhaQiaQjaQgaQgaQkaQeaQlaDUaQmaDUaQnaQobVfaDUaQrbyxbyxbyxbyxaQsaQtaQuaQvaQuaQwaQxbyxbyxaQyaOZaOZaOZaOZaQzaQAbVVbVYbVXbNtaQEaPfaQFbCtbCtbCtbCtbCtbCtbCtaPjaPjbScaQGaQHaQIaQJaQKaQLaQMaQNbTcaQOaQPaQQaQRaQSbTcaQTaQUaQVaQWaQVaQXaRaaQYaQZaRbaRcaRdaReaRfaRgbTYaRhaMabWaaRjaRkaPxaRlaPzaPAaRmbLNaRnaRoaRpaRqaRraObaObbLNbLNaMtaMuaMvaRsaRtbEFaRuaRvaRwaRxaRyaRzaMFaMFaRAaMHaaaaaaaaaaaaaaaaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPNaIbaIcaIbaIbaIdaIeaIbaIbaIcaPOaRBayaaRCaPTaCyaRDaRDaREaRDaRFaySaRGaRHaDyaRIaRJaRKaRLaRMaRNaRLaROaRLaRLaRLaRPaRLaRLaRQaRRaRSaRTaRUaRVaRTaRWaRTaRTaRTaRTaRXaRYaRZaRLaRLaSaaSbaScaSdaSeaSfaSgaShaSiaSjaSkaSkaSkaSkaSkaSkaSlaSmaSnaSoaSpaSqaSraSsaStaSuaOZaOZaSvaSwaSxaSwaSyaSzaSAaSBaSCaSDaSEaPjaSFaSGaSHaSIaSJaSJaSKaSLaSMaSNbTcaSOaSPaSQaSQaSRbTcaSSaSTaSUaSVaSWaSWaSXaSZdhSaSYaTaaTbaTcaTdaTebTYaPvaTfbLLaTgaThaThaTiaTjaThaTkbLNaTlaTmbLNaTnaToaObaTpbLNaTqaTraTsaMvaOeaOebEFaTtbIgbWdbWebIgbIgbIgbIgbIgabAacOaaaaaaaaaaaaaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCyaTuaTvaHcaHcaHcaHcaTwaTuaCyaHeayaaTxaTyaTzaTAaTBaTCaTCaTDaySaTEaRHaTFaTGaRJaTHaTIaTJaTKaTKaYgaTLaTLaTLaTMaTNaTNaTOaTPaTQaTKaTKaTRaTSaTTaTUaTVaTVaTWaTVaTXaTSaTSaTSaTYaSbaScaSdaSeaSeaSeaSeaTZaSeaSeaSeaSeaSeaSeaUaaUbaUcaUdaUeaUfaUgaUhaUiaUjaUkaUkaUkaUlaUmaUmaUmaUnaSEaSEaSEaUoaUpaSEaPjaUqaUraSJaSJaUsaSJaUtaUuaSMaUvbTcaUwaUxaUyaUzaUAbTcaUBaUCaUDaUEaUFaUGbTYbWQaUIbWQbTYbTYbTYbUmbTYbTYaPvaJubLLaUJaNRaNRaNRaUKaNRaULbLNbLNbLNbLNbLNbLNbLNaUMbLNaMvaMvaMuaMvaUNaUOaOeaUPaUQaURaUSaUTaUUaUVaUWaUXaaaaaaaaaaaaaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaGbayaaTzaAPaGdaUYaUZaVaaVbaGdaAPaVcaVdayaaVeaPTaTzaVfaVgaTCaTCaTDaySaVhaRHaDyaTGaRJaViaVjaVkaRLaRLaVlaVmaVnaRLaVoaVpaVqaVpaVraVsaVpaVpaVtaVpaVpaVuaVvaVpaVwaVpaVxaRLaRLaRLaVyaVzaVAaVBaVCaVDaVCaVEaVFaVEaVEaVEaVEaVEaVEaVGaVHaVIaVIaVIaVIaVJaVIaVKaVLaVIaVIaVMaVNaVOaVOaVOaVOaVOaVOaVOaVPaSEaSEaPjaVQaVRaVSaVTaVTaVUaVVaUuaSMaVWbTcbTcbTcbTcbTcaVXbTcaVYaVZaWaaWbaQVaWcbTYaWdaWeaWfaWgaWhaWiaWjaWkbTYaPvaJubLLaWlaWmaNRaWnaWoaNRaWpaWpbLLaWqaWraWsaOeaWtaWuaWvaMvaMvaWwaWxaOeaWyaOeaWzaUQaURaWAaWBaUQaUQaWCaWDaaaaaaaaaaaaaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaySaDwaTuaPSaERaDyaDyaESaPSaTuaPSaWEaWFaWGaWHaDwaWIaWIaREaWIaRFaySaWJaRHaDyaySaPYaPYaWKaYraYraYraYraYraYraWLaWMaYraYraYraYraYraYEaWNaWOaWNaYEaWPaPYaWQaVjaWRaWSaWTaWUaRLaWVaPYaWWaWWaWXaWXaWXbXMbXNbXNbXNbXNbXNbXNbXNbXObYMbYmcbAbYmcbBcbBcbGcbDcbZcbYccwbXOccIbVYbVYbVYbVYbVYbVYccJaXkaXkaXkaPjaXlaXmaXnaXnaXnaXnaXoaKyaXpaXqaXraXsaXtaXuaXvaXwbTcbTcaXxccOcencdjcfnbTYaXAaXBaXCaXCaXCaXCaXDaXEbTYaXFaJubLLaXGaNRaWnaWnaWoaWnaNRaXHbLLaXIaXJaXKaOeaMvaXLaXMaXNaXNaXOaXPaXQaXRcfoaXSaXTaXUaXVaUSaUQaUQaXWaWDaaaaaaaaaaaaaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCyaXXaDyaXYaXZaYaaYbaYcaYdaYbaYeaYfaYbaYbbcOaYhaYiaYjaYkaYkaYkaYlaYkaYmaYnaySaYoaYpaYqaYraYsaYtaYuaYvaYwaYxaYyaYzaYAaYBaYCaYDaYEaYFaYGaYHaYEaYIaZYaZYaYJaZYaZYaYMaYMaYKaYLaYMaYMaYMaYNaSeaSjcfsaaaaaaaaaaaaaaaaaaaaabXOaYPaYQaYRaYSaYTaYUaYVaYWaYXaYYaYZbXOaaaaaaaaaaaaaaaaaaaaacftaZaaSEaZbaPjaZcaXmaXqaXqaXqaXqaXqaZdaZeaXqaXqaXqaXtaZfaZfaZgaZhaZiaZjaZkaZlaZmaZnbTYaZoaZpaZqaZraZraZqaZsaZtbTYaPvaZubLLaZvaZwaNRaWnaWoaNRaZxaZxbLLbLLaZybLLaOeaZzaWuaWxaZAaZAaZBaWxaOeaOeaOeaZCaUQaZDaZDaZEaZDaUQaZFaWDaaaaaaaaaaZGaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDwaZHaZIaZHaZHaZHaZHaZHaZHaZIaZHaZHaZJaDyaZKaZLaDyaDyaZMaDyaZNaZOaZPaZQaZRaySaYpaYpaZSaYraZTaYxaYxaYxaYxaYxaYyaZUaYxaYxaYxaYxaYEaZVaZWaZXaYEaYIaZYaZZbaababbacaYMbadbaebafbagbahbaiaYNaSeaSjcfsaaaaaaaaaaaabXObXObXObXObajbakbalbambanbaobapbaqbarbasbatbXObXObXObXOaaaaaaaaaaaacftaZaaSEaSEbauaXqbavbawbaxaXqbaybazaJabaAbaBbaCaXqaXtdqXaZfbaDbaEaZfbaFbaGbaHbaIaZfcfubaKbaLaZqaZraZraZqbaMbaNbTYaPvbaObLLaXGaNRaWnaWnaWoaWnaNRaNRbaPbaQaNRbaRaOebaSbaTbaUaZAaZAbaVbaUbaWaOebaXbaYaUQbaZbaZbbabaZaUQaXWbbbbbcbbdbbdbbeaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayaayabbfbbgbbgbbgbbgbbgbbgbbgaGjayaaySbbhbbibbjbbjbbjbbjbbjbbjcfvbbjbbjbbjaySaYpbblbbmaYrbbnaYxaYxbbobbpbbqbbrbboaYxaYxaYxbbsaYEbbtbbubbvaYEaYIaZYbbwbbxbbybbzaYMbbAbbBbbCbbDbbEbbFbbGbbHaSjcfwcgtaQqbXObXObXObbJbbKbbLbbMbbNbbNbbObbPbbNbbQbbNbbRbbSbbTbbUbbVbbWbXObXObXOaQqccIcgIaZaaSEaSEaPjbbYbavbaBbaxaXqbbZbcaaXqbcbbccbaCaXqaXtaZfaZfbcdbcebcfbcgbchbcibcjaZfcgVbaKbclaZqaZraZrbcmbcnbaNbTYaPvbcobLLbcpbcqbcraWnaWobcsaNRaNRbctaNRbcubcvaOebcwbcxbcyaZAaZAbczbcybcAaOebcBbaYaUQaUQaUQaUSaUQaUQbcCbcDbcEbcFbcGbcHaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIaabbcJaGeaDAbcKbbjbcLbcMbcNbcRbcPbcQbhlbcSbbjbcTbcUbcVbcWaYrbcXaYxaYxbbobbqbcYbcZbboaYxaYxbdabdbaYEaYEaYEaYEaYEaYIaZYaZYaZYaZYaZYaYMbdcbbDbddbbDbdebbFaYNbdfaSjaSkaSkbdgcgWbdibXObdjbalbdkbbNbbNbbNbdlbdmbdnbdmbdobdpbdqbdmbdrbdsbdtbXObducgWbdvbdwbdxaZaaSEaSEbauaXqbdyaXqaXqaXqbdzbdAaXqbcbbdBbaCaXqaXtaZfaZfbdCbdDbdEbdFbdGbdHbcjbdIbTYbdJbclaZqaZraZraZqbcnbdKbTYbdLchpbLLchqbLLbLLbdMaWobdNbdOaNRbdPbdQaRlbdRcfobdSbdTbdUbdVbdVbdWbdXbdYcfobdZbeaaUQbebaUQaUSaUQaUQbecbedbbcbbdbbdbeeaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbefbegbehaERaZKbbjbcLbeibejbcLbekbelbembenbbjbeobepbeqberaYrbesbetbeubevbewbexbeybezbezbezbeAbeBaYrbeCbcUbeDbeEbeFbblbblbeGberbeHaYMbeIbeJbeKbeLbeMbeNaYNbdfaSeaSeaSebeObePbeQbeRbeSbeTbbNbeUbeVbeWbeXbeYbeZbfabfbbfcbfdbfebeSbffbfgbfhbfibfjbfkbflbfmbfnaSEbfoaPjaXqbfpbfqbaCaXqbfrbfsaXqbftbfubaCaXqaXtaZfaZfaZfaZgaZfbfvaZfbdHbcjbfwbTYbfxbclaZqaZraZraZqbcnbfybTYbfzbfAbfAbfBbfCbfDbfEbfFbfGbfGbfGbfGbfGbfGbfHbfIbfJaZAaZAaZAaZAaZAaZAbfKbfLbfMbaYaUQaUQaUQaUSaUQaUQbfNaWDbfObfObfOaWDaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaabcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbfPbfQbfRbfSaZKbbjbfTbcLbfUbfUbfUbfVbcLbfWbbjbfXbfYbeqbfZbfZbfZbfZbgabfZbgbaYxbgcbgdbgebgebgfbggaYrbghbgibgjbgkbglbgmbgmbgnbgobgobgpbgpbgpbgpbgpbgqaYMaYNbgrbgsbgtbgubgvchrbgxchsbgybeZbgzbgAcNxcNxcNxcNxbgBcNxdiMdiOdiNbgFbgzbgGbgHbXObgIchtbgKbgLbgMbgNaSEaSEbauaXqbgOaXqaXqaXqaLLaXqaXqbgPbgPbgQbgQbgRaZfaZfbgSbgTaZfaZfaZfbgUbgVbgWbTYbaNbclaZqaZqaZqaZqbcnaXEbTYbgXbgYbgYbgZbgYbhaaWnaWnaWnaWnbhbaWnaWnaWnbhcbfLaZAaZAaZAaZAaZAaZAaZAbfKbfLbfMbaYaUQaZDaZDaZEaZDaUQbhdaWDbhebhfbhgaWDaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbhibhjbehbhkaWHbjQbcLbhmbfUbfUbfUbfVbhmbcLbbjbhnbhobeqbfZbhpbhqbhrbhsbfZbhtbhubhvaYrbhwbhxbhybhzaYrbblbhAbhBbhBbhCbhBbhBbhBbhBbhDbhEbhEbhEbhFbhEbhGbiWbhHbhIbhJchuchuchuchuchuchucjcbhKcjccNxcNxbhLbhMbhNbhObhPbhQbhLdiPcNxcjVbhRcjVcjVcjVcjVcjVcjVcjVbgNaSEaSEaPjbhSbhTaXqbhUaXqbhVaXqbhWbhXbhYbgQbhZbTcbiabibbTcbTcbicbidbidbidbTcbTcbTYbiebifbigbigbigbigbifbihbTYbiibgYbgYbgZbijbLLbikbilbimbinbiobipbiqbirbisaOebitaMvbiuaZAaZAbiuaMvbivaOebiwbaYaUQbaZbaZbbabaZaUQbfNaWDbfObfObfOaWDaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbcIbixaDwbiybizbiAbbjbeibeibeibcLbiBbiCbiDbiEbbjbiFbiGbeqbfZbfZbfZbiHbiIbfZbiJbiKbiLaYrbhwbhxbhybiMaYrbblbhAbhBbiNbiObiPbiQbiRbhBbiSbiTbiUbiVbiWbiWbiWbiWbiXbiYbiZchubjabjbbjcbjdbjebjfbjgbjhcNxbjibhNbjjbjkbjlbjkbjjbhNbjmcNxbjnbjobjpbjqbjrbjsbjtbjucjVbjvbjwbjwcmhaPjaPjaPjaPjbjybaubjycmSaPjbSYaPjaPjbTcbTcbTcbTcbjAbjBbjBbjBbjBbjCbjDbTYcncbjFcncbjGbjGcncbjFcncbTYbiibgYbgYbjHbijbLLbLLbLLbLLbLLchqbLLbLLbLLbLLaOecndcnQcnecnecnecnecoLaOeaOebjJbjKaUQaUQaUQaUSaUQaUQbecbbbbjLbbdbbdbjMaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGbayabjNaHcbehaySaySaySaySaySaySbjObjPbbjbbjbbjbbjbbjbbjccWbbjbbjbbjbjRbjRbjSbfZbjTbjUbiHbjVbfZbjWbjXbjWaYrbhwbhxbhybjYaYrbblbhAbhBbjZbkabkbbiQbkbbhBbiSbkcbkdbkebkfbkgbkhbiWbkibkjbiZcoMbklbkmbknbkobkobknbkpbkqcNxbkrbhNbhNbksbktbjkbjjbhNbkudiNbkvbkwbkxbkybkzbkAbkxbkBcjVbkCbkDbkEbkFbkGbkHbkIbkJbkJbkJbkJbkJbkJbkKbkLbkMbkNbkJbkObkJbkJbkJbkJbkJbkJbkJbkJbkPbkQbkRbkRbkRbkRbkRbkRbkSbkHbkTbkUbkUbkVbkWbkXbkWbkYbkWbkZblablbbkWblcbldbleblfblgblgblgblgblgblgblgblhblibljbljbljbljblkbljbllblmblnbloblpbcGblqaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaablrblrblrblrblrblrblrblrblrblraaaaabblsaGebltblublvblwblwblwblwblwblxblyblzblAblBblCbjSbfZbfZbfZblDbiIbfZaYraYraYraYrbhwblEblFblGaYrblHblIbhBblJblKbiQbkbblLbhBbiSblMbkdbkebkeblNblObiWblPbkjbiZcoNblRblSblTblUblVblWbkpblXcNxblYbksbhNblZbmablZbhNbksbmbdiPbmcbkxbkxbkybmdbkAbkxbmecjVbmfbkEbkEbkFbkGbkHbkJbkJbkJbkJbkJbkJbkJbmgbkJbkJbkJbkJbkJbkJbmhbmibmibmibmibmibmibmibmibmibmibmibmibmibmibmjbmkbmlblgblgbmmbgYbgYbgYbgYbgYbgZbgYbgYbgYbgYbgYbgYbgYbgYbgYbgYbgYbgYbmnbgYbmobmpaUQaUQaUQaUQaUQaUQaUQbmqbedbbcbbdbbdbbeaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaablrblrblrblrblrblrblrblrblrblrblrbefbegbmrbmsbmtbmubmubmubmvbmubmubmubmwberberberberbeqbfZbhpbmxbmybjVbfZbmzbmAbmzaYraYraYraYrbmBaYrbmCbhAbhBbmDbmEbkbbmFbmGbhBbiSbiWbmHbkebkebkebmIbiWbmJbkjbiZcoObmLblSblTbmMbmNblWbkpbmOcNxbmPbmQbhNbmRbmSbmTbjjbmUbmVdiQbmXbmYbmZbnabnbbncbkxbndcjVbnebnfbkEbkFbkGbkHbkJbngbkJbkJbkJbkJbnhbnibnibnibnibnjbkJbkJbkJbkJbnkbkJbngbnlbkJbnmbnnbnobkJbnpbnqbnqbnrbnsbntbnubgYbgYbgYbgYbgYbgYbgYbnvbnwbnxbgYbgYbgYbgYbgYbgYbgYbgYbgYbgYbnybnzbnzbnAbnBbnCbnDbnEbnEbnEbnEbnFbnGbnHaabaaaaaaaabaKPaKPaKPaKPaKPaKPaaaaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaablrblrblrblrblrblrblrblrblrblrblrbnIbnJbnKbnLbnMbmubnNbnObnPbnPbnQbnRbnSbnTbnUbnUbnVbnWbfZbfZbfZbiHbnXbfZberberberberbnYbblbblbnZbgmboabobbocbodboebofbogbohbhBboibiWbojbkebkebkebokbolbombkjbonchuboobopbknbknbknbknbkpboqcNxdiRdiScNxcNxcNxcNxcNxcNxcNxdiPcjVbosbotboubovbowboxboycjVbozboAboAcpTcpTcpTcpTcpTcpTcpTcqxcqxcrkcqBboDboDcqBcrkcqxcqxcrtcrtcrtcrtcrtcrtcswcswboEcswcswcswcswcswctpboFcvyboGbgYbgYboHboHcxOcxOcxOcxOcxOboIbnzbnzbnybnzbgYbnzbnzbnzbnzboJcxQcxQcxQcxQboKcxYcxYcxYcxYcxYcxYcxYcxYcxYaaaaaaaaaaaaaKPaKPaKPaKPaKPaKPaaaaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaablrblrblrblrblrblrblrblrblrblrblrbhibhjbmrbmsboLbmuboMbmuboNboObmubmubmuaZSboPboQboQboRbfZbhpboSbiHboTbfZboUboVboWboXboYboZboZbpaboZbpbbpcbhBbpdbpebiQbpfbpgbocbphbiWbpibkebkebpjbpkbplbombkjbpmchubpnbpobppbpqbprbpsbptchuchubpuczkbpvbpwbpxbpwbpyczkaaaczEcjVbpzbpAbpBbpCbowbkxbpDcjVbpEbpFbpGcpTbpHbpIbpJbpKbpLcAgbpNbpObpPbpQbpRbpRbpQbpSbpTbpUcrtbpVbpWbpXbpYcrtbpZbqabqbbqcbqdbqebqebqfctpbqgcBocAMbqhcAMbqibqicxObqjbqkbqlcxOcBSbqncBScxObqobnzboJcxQcCqbqqcCqcxQbqrbqscxQbqtbqubqvcDsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaKPaKPaKPaKPaKPaKPaaaaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaablrblrblrblrblrblrblrblrblrblraaabqwaTzbqxbizbqybmubqzbmubqAbqBbqCbqDbmubqEbqFbqGbqHboRbfZbfZbfZbfZbfZbfZbqIbqJbqKbqLbqMbhBbhBbhBbhBbhBbhBbhBbqNbhBbhBbhBbqObhBbqPbqQbqRbkebkebkebqSbolbqTbkjbqUchubqVbpocjccjccjcchubqWchubqXbqYcDXbqZbrabrbbrcbrdcDYbrebrfcjVbrgbkxbrhbribowbrjbkxcjVbrkbrlbrmcpTbrnbrobrpbrqbrrbrsbrtbpRbpRbpRbpRbpRbpRbpRbrubrvcDZbrxbrybrzbrAcrtbrBbrCbrDbrEbrFbrGbrCbqfctpbrHcBobrIbrJbrKbrLbrLcEFbrMbrNbrObrPbrQbrRbrScxOcFEbrTcGWcxQbrUbrVbrWbrXbrXbrYcxQbrZbsabsbcDsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaKPaKPaKPaKPaKPaKPaaaaKPaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGbayabjNaHcbhjbbgbbgbbgbscbbgbsdaERbsebsfbmubsgbshbsibsjbskbslbsmbcWbblbblbblbsnbnUbnUbnUbnUbnUbnUbsobspbspbsqbsrbhBbssbstbsubsvbswbsxbsybszbsAbsBbsCbsDbphbolbqRbkebkebsEbiWbiWbsFbsGbsHcGXbsIbsJbsKbsLcIWbsMbsNcJFbsObsPcDYbsQbsRbsQbsRbsScDYbrebsTdjnbsUbsVbsWbsXbsYbsZbtadjnbtbbpFbpFcpTbtcbtdbtebtfbtgcpTbrtbpRbpRbpRbpRbpRbpRbpRbthbtibtjbtkbtlbrxbtmcrtbtnbtobtpbrEbqfbrGbtqbtrctpbtseKcbtubtvbtvbtwbtxbtybtzbtAbtAbtAbtBbtAbtCeKdbtEbtFbtGeKebtHbtIbtJbtJbtJbtKcxQbtLbsabtMcDsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaKPaKPaKPaKPaKPaaaaKPaKPaKPaKPaKPaaaaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaMIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtNbtObtPbtQbtRbtSbtSbtTbtUaDybmubtVbtWbsjbtXbmubmubmuberbtYbtZbuabubbuabuabuabubbuaberberbhBbhBbhBbucbhBbudbudbudbudbudbudbsybuebufbugbuhbuibujbukbulbumbunbuobupbuqburbusbutbuubuvbuvbuwbuxeKfbuybuzeKgbuAbuBczkbuCbrcbuDbrabuEczkaaabuFeKheKibuGeKheKheKheKhbuHcjVbuIbpFbuJeKjbuKbuLbuMbuNbuOcpTbuPbuQbuRbuSbuTbuUbuVbuWbrubuXcrtbuYbtlbuZbvacrtbvbbvcbrDbrEbqfbrGbrCbqfctpbrHcBobvdbvebvfbvgbvheKkbvibvjbvkbvlbvmbvnbvocxObvpbvqbvrcxQbvsbvtbvubrXbvvbvwcxQbtLbsabvxcDsaaaaaaaaaaaaaabaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaabtNbvybvzbvAaDxaDxbvBbvCaDxbvDbmubvEbvFbvGbvHbmuaaaaaaaaaaabaabbvIbvIbvIbvIbvIbvIbvIaaaaaabvJbvKbvLbvMbvNbudbudbudbudbudbudbvObvPbvQbvRbvSbvTbvUbvVbiWbiWbvWbiWbiWbiWbvYbvZbwaeKlbwbeKmeKmeKneKmeKobwceKpbwdbuBczkbwebpwbpwbpwbwfczkaaabuFeKhbwgbwhbwibwjbwkeKqbwleKrbwmbpFbwncpTbpHbwobwpbwqbwreKsbwtbwubwvbwwbwxbwybwzbwAbwBbwCeKtbwDbtlbwEbwFcrtbwGbwHbwIbwJbwKbwLbwMbqfctpbwNeKubwPbwQbwQbwRbwSeKvbwUbwVbwWbwXbwYbwZbxacxObxbbvqbxccxQbxdbxebxfbrXbrXbxgcxQbrZbsabxhcDsaaaaaaaaaaaaaabbxibxjbxkbxjbxkbxjbxlaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabxmaDwbxnbxnbxobbgbxpaGbayabxqbxpbmubxrbxsbxtbxubmuaaaaaaaaaaaaaaabvIbvIbvIbvIbvIbvIbvIaaaaaabxvbxwbudbxxbxybxybxybxybxybxzbxAbxybxBbxCbxDbxEbxFbxGbxHbiWbxIbkebxJbxKbxLbxMbxNbxOeKleKleKpbxPbxQbxRbxSbxTeKpbpubuBczkbxUbxVbxWbxXbxYczkaaabxZeKhbyabybbyceKwbydeKwbyeeKxbyfbpFbygcpTeKzeKyeKAbyjeKCeKBbylbymbynbyobypbypbyqbyrbysbytcrtbwDbyubyvcrtcrtcsweKDeKFeKEcswctpctpctpeKGbyycBobyzbvebvfbyAbwQeKHbyCbyDbyDbyEbrObyFbyGeKJeKIbrTeKKcxQbyJbyKbrXbyLbyMbyNcxQbtLbyOcDscDsaaaaaaaaaaaaaabbyPbyQbyRbySbySbyTbyPaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvIbvIbvIbvIbvIbvIbvIbyWbyXbyYbFbbyZbzabzbbzbbzbbyZbudbsybuebudbudbufbzcbzdbzebzfbzgbzhbzibkebkebzjbzkbxMbxNbzlbzmbznbzobzpbzqbzrbzsbzteKpbzubzvcDXbzwbzxbzybzzbzAcDYbrebzBeKhbzCbzDbzEeKwbzFeKwbzGeKxbzHbpFbzIcpTbzJbzKbzLbzMbzNeKLbzObzPeKMeKMeKNbzReKMeKMbzSbzTeKPeKObzUbzVbzWbzXbzYbzZbAabAbbAceKQbAdbAebAfbAgcBobAhbAibAjbAkbAlcEFbAmbyDbyDbAnbAobyFbApcxObAqbAqbArcxQbAsbAtbAubAvbrXbAwcxQbtLbAxcDsaaaaaaaaaaaaaaaaabbAybAzbyRbySbyRbAAbxkaabaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvIbvIbvIbvIbvIbvIbvIbABbACbABbADeHueHveHueHueHueHubAEbsybuebAFbhBbhBbAGbkebuhbzfbAHbAIbAJbAKbAKbALbAMbANbAObAPeKRbARbASbATbAUbAVbAWbAXeKpbwdbuBczkbAYbAZbBabBbbBcczkaaabxZeKSeKTeKSeKSeKSeKSeKSbBdeKSbBebpFbzIcpTbBfbBgbBgbBhbBieKBbBjbBkeKUbBmbBnbBobBpeKUbBqbBrbBsbBtbBubBvbBwbBwbBxbBybBzbBAbBBbBCbBDbBEbBFbBGbBHbBIbBIbBJbBKbBLcEFbBMbrObrObBNbBObyFbBPbBQbBRbBSbBTeKVbBUeKXeKWbBWeKYcxQcxQbBXeKIeKIeKZeLaeLaeLaeLbeKIbyPbySbyRbySbySbCbbyPaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaagaaaaaaaaabvIbvIbvIbvIbvIbvIbvIbCcbCdbCcbCebudbzabzbbzbbzbbudbudbsybuebCfbCgbhBbChbkebuhbzfbCibCjbCkbkeblNbkebClbxMbpFbCmeLcbARbCnbCobCpbCqbCrbCseLdeLfeLeeLgeLgbCubCvbCwczkczkaaabxZeKSbCxbCybCzbCAbCBbCCbCDeLhbCEbpFbzIeKsbCFbCGbCHbCIbCJeKBbCKbCLbCMbCNbCObCPbCQbCRbCSbCTbCUbCVbCWbCXbCYbCZbDabDbbDcbDdbDeeKQbDfbDgbDhbDicAMbDjbDkbDlbDmbDmcEFbDnbDobDpcEFbDqbyFbDrcEFbDsbDtbDubDvbDwbDxbDybDzbDAbDBbDCbDDbDEbDFbDGbDGbDHbDIbDJeLibDLbxjbxkbDMbxkbxjbDNaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvIbvIbvIbvIbvIbvIbvIbDObyXbDPbDQbudbzabudbudbudbudbudbsybuebCfbDRbhBbFnbkebDTbDUbkebDVbkdbkebkebdhbxLbxMbpFbCmeLcbAReKpbDXbDYbDZbEabEbeLjbEcbEdbEeeLkcDYbEfeLlcDYbrebrebEheKSbEibEjbEkbElbEmbEmbEnbEobEpbpFbEqcpTeKBbEreLneLmbEteKBbCKbEueLobEvbEwbExbEyeLobCKbEzbEAeLpeLpeLpeLqeLpeLreLrbEBeLseLueLteLtbECeLueLueLteLteLweLveLweLwcEFcEFcEFcEFcEFeLxbEEeLycEFbEGbEHbEIbEJbEJbEKbELbEMbENbEObEPbEQbERbESbETbETbEUbDwbEVeKIeLzeLBeLAbEZeKIbFaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabhhbhhbhhbhhbhhbhhbhhbhhbhhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvIbvIbvIbvIbvIbvIbvIbCcbCdbCcbFbbFcbFdbudbudbudbFcbudbsybuebCfbFebhBbFfbkebuhbzfbkebolbFgbkebkebFhbzkbxMbpFbFieLCbFkeKpbFlbFmeHrbFobFpeLjbFqbFrbFsbFtbFubFvbFweLDaaaaaaaaaeKSbFxbFybFzbFzbFAbFBbFCeKSbFDbFEbzIbFFbFGbFHbFIbFJbFKbFLbFMbCLeLEbFNbFObFPbFQeLEbCKbEzbFRbFSbFTbFUbFVbFWeLrbFXbFYbFZeLubGabGbbGcbGdbGebGfeLFbDBbGhbEJbEJbGibGjbEJbGkbGlbGmbGnbGobEJbGpbGqbGreLHeLGeLJeLIeLKeLIeLIeLIbBXeKIeKIeKZeLbeKIbGvbGwbGxbGybGzbGAbGBeLLaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvIbvIbvIbvIbvIbvIbvIbGDbGEbGDbGFbGGbGHbGHbGHbGHbGHbGIbGJbGKbCfbGLbhBbGMbGNbGObGPbGQeLNeLMeLPeLObIybIybGUbpFbGVbGWbAReKpbGXbGYbGZbDYbHaeLjbHbbHcbHdeLQbHebzybHfeLDaaaaaaaaaeKSbHgbHhbHibHjbFAbFBbFCeKSbHkbHlbHmbHnbHobHpbHqbHrbHsbHtbHubHveLoeLoeLRbHxeLoeLobCKbEzbHybHzbHAbHBbHCbHDeLrbHEbHFbHGeLSbHIbHJbHKbHKbHLbHMeLTbHObHPbDwbDwbHQbDwbHRbDwbHSbDwbHTbHUbHUbHVbHWbHXeLUbHZbIabIbbIcbIdbIeeLIbIfeLVaaaaaaaaaeKIbIhbIibIjbIkbIlbImbIneKIaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvIbvIbvIbvIbvIbvIbvIbIobIpbIqbhBbhBbIrbyXbyXbyXbIsbhBbhBbItbIubIvbhBbIwbIwbIwbIxbIwbIybIzbIAbIBbICbIybxMbpFbIDbvXbvXeKpeKpeKpeKpeKpbIEeLjeLgeLeeLXeLWeLYbIFeLDeLDczkczkczkeKSeKTeKSeKSeKSeKSeKSeKSeKSbIGbpFbIHeLZbUcbIIbIJbUcbUcbCKbIKbILbIMbINbIObIPbIQbIRbFMbISbITbIUbIVbIWbIXbIYbIZbJabJbbJceMabJebJfbJgbGcbJheLteLtbKJbKJbKJbKJbJibKJbKJbKJeMbbJjeMceMcbJkbJlbJmbJneLUbJobJpbJqbJrbJsbJteLIbIfeMdaaaaaaaaaeKIbJvbJweKIeLieKIeKIeLieKIaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvIbvIbvIbvIbvIbvIbvIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabJxaabaaaaaaaaaaaabIwbJybJzbJAbJBbIybJCbJDbJEbJFbIybxMbpFbJGbJHbJIbJJbJKbJLbJMbJNbJObJPbJQbJRbJSbJTbJUbJVbJWbJXbJYbJZbKabKbbKcbKdbKeboAbKfbpFbKgbKhbKibpFbKjbUcbKkbKlbKmbKnbKobCKbKpbKqbKrbKsbKtbKubKvbKwbKxbKybKzeLpbKAbHBbKBbKCeMebKEbKFbKGeLubKHbGcbGcbGcbKIeLtbKJbKKbKLbKMbKNbKObKPbKQbKJbKRbKSbKTeMceMcbKUbJmbKVeMfbKXbKYbKZbLabLbbLceLIbLdcDsaaaaaaaaaeKIeKIeKIeKIaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMIaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvIbvIbvIbvIbvIbvIbvIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIwbLebLfbLgbLhbLibLjbLkbLlbLmbIybxMbLnbLobpFbpFbzIbLpboAbKebKdbLqbLrbLqbLsbLtbLtbLubLvbLwbLtbLtbLxbLtbLybLtbKdbKeboAbLzbLAbLBbLCbLDbLEbpFbUcbLFbKlbLGbLHbLIbCKbLJbLKeMheMgeMibLOeMkeMjbCKbLRbLSeLpbLTbLUbLUbLVeMlbLWbLXbLYeLubLZbMabGcbMbbMceLtbKJbMdbMebMfbMgbMhbMibMjbKJbMkbKSbMlbMleMcbMmbMnbMobMpbMqbMrbMsbMtbMubMveLIbIfcDsbMwaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvIbvIbvIbvIbvIaaaaaaaaaaaaaaaaaaaaaaaabMxbMybMzbMybMAaaaaaaaaabIwbIwbMBbMCbLgbMDbMEbMFbJEbMGbMHbIybxMbMIbMJbMKbMLbMMbMNbMObMPbMQbMRbMSbMTbMUbMVbMVbMWbMXbMXbMXbMXbMXbMXbMYbMZbNabNbbNcbNdbMLbNebNfbNgbNhbNibUcbNjbKlbKmbNkbLIbCKbLJbLKeMmbNmbNnbNobNpeMnbCSbNrbNseLpeLpeMoeMpeLpeMleLreMreMqeLubNvbNwbNxbNybNzeLtbKJbNAbNBbKMbNCbNDbNEbNFbKJbNGbKSbMlbMleMcbNHbNIbNJeMsbNKbNLbNMbNNbNObNPeLIbIfeMteMueMteMweMveMweMweMwaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabNSbNTbNUbNVbNSbNWbNXbNYbIwbNZbOabObbOcbOdbOebOfbOgbOgbOhbIybOibOjbOkbXibXibOlbOmbOnbXicblcblbOobOpbOqcblcblbOrbKdbKdeMxeMyeMyeMyeMzbOteMyeMyeMAbOueMBeMBbOveMBbOweMCeMBeMDbOybOzbUceMEbOBbLJbOCeMFbODbOEbOFbOGeMFbCKbLRbOHeMGbOIbOJbOKbOLbOMbONeMHbOObOPbOQbORbOSbOTbOUeLtbKJbKJbKJbKJbKJbKJbKJbKJbKJbOVbOWbOXbOXeMcbOYbOZbPaeLIeLIeLIeLIeLIeLIeLIeLIbIfeMtbPbbPceMIbPebPebPfeMwaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeMKeMJeMJeMLeMMeMMbQZbQZbQZbQZeMNaabaabaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabMzbPibPjbPibMzbPkbPlbPmbPnbPobPpbPqbPrbPsbIybPtbPubPvbPwbIybOjbOjbPxbXibPybPzbPAbPBbPCcblbPDbPEbPFbPGbPHcblbPIbPJbPKeMybPLbPMbPNbPObPPbPQbPReMObPTeMPbPUbPVbPWbPXbPYbPZbQabQbbQcbQdbQebQfbQgbLKbQhbQibQjbQkbQlbQmbCSbQnbQobQpbQqbOKbQrbQrbQsbQteLubQubQvbQwbQxbQybQzbQAeLtbQBbQCbQDbQEbQDbQDbQFeMReMQbQGbQHbQIbQJeMcbQKbQLbJneKIbsabQMbQNbQObQObQNbQObQPeMtbQQbQReMIbPebQSbQTeMwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeMSbQVbQWbQVeMMbQZbQZbQXbQYbQXbQZbQZaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabNSbPibPibPibRabRbbMCbRcbRdbRebMCbPqbRfbRgbIybIybIybIybIybIybRhbOjbRicbXbRjbRkbRkbRkbRlcblbRmbRnbRnbRnbRoeMTbRpbRqbRreMUbRsbRtbRubRvbRwbRxeMyeMAbRyeMBbRzbRAbRBbRCbRDeMBbLFbKmbLGbLHbREbRFbRGbRHeMVbRIbRJbRKbRLeMFbRMbRNbROeMWbRPbRQbRRbRSbRTbRUeLueLueLueLueLueMXeMZeMYeLtbRVbQDbQDbRWbQDbRXbRYeNbeNabRZbKSbSabSaeMcbJlbSbbJneKIeMteNceMteMteMteMteMteMteMtbSdbSeeMwbSfbSgbSheMwaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacbSibQVbQVbSjbQZbQZbQXbQXbSkbQXbQXbQZbQZaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabMzbPjbPjbPjbMzbSlbSmbSnbSobSpbMCbSqbSrbSsbStbSubSubSubSvbOjbOjbOjbPxbXibRlbRkbSwbRkbSxcblbSybRnbSzbRnbSAcblbSBbSCbSDeMybSEbSFbSGbSHbSIbSJeNdbSKbSLeNebSMbSNbSObSPbSQeMBbNjbKmbKmbSRbREbRFbSSbSTeNfbQibSVbSWbSXeNgbSZbTabTbeNhbTdbTebTfbTfbQrbTgeMGbThbTibTjbTkbTlbTmbTneNbbRVbTobQDbQDbQDbTpbTqeNbeNabTrbKSbSabSaeMcbTsbTtbJneKIbTubTvbTweMtbTxbTybTzbTAbTBbTCbTDeMwbTEbTFbTGeMweMteMteMteMteMteMteMteMtaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaeNibQZbSibQZbQZbQXbQXbQXbQXbQXbQXbQXbQZbQZaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaaaaaaaaaaabyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVbyVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaabNSbTIbTJbTKbNSbTLbNXbNYbIwbIwbTMbTMbTMbIwbIwbOjbTNbTNbTObTPbOjbTQbTRbXibRlbRkbRkbRkbTScblbSybRnbRnbTTbTUeNjbTVbTWbTXeMyeMyeMyeMyeMyeNkeMyeMybTZbUaeMBeMBeNleMBeMCeMBeMBbUcbUdbUdbUcbUcbUebUfeNmeNnbUibUjbUkbUleNoeNpbUnbTbeNqbUpbUqbUrbUsbUtbUueMGbUvbUwbUxbUybUzbUAbUBeNrbUCeNrbUDbUEbUFeNreNseNreNrbUGbUHbSabSaeMcbUIbSbbJnbUJbUKbULbUMbUNbUObUPbUPbUQbURbUSbUTbUUbUVbUWbUXbUYbUZbVabVbeNtbVcbVdbVeeNuaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaaeMMbQZbVgbVhbVhbQXbQXbQXbQXbQXbQXbQXbQXbQZbQZaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabyUbyUbyUbyUbyUbyUbyUbyUbyUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabVibMybVjbMybVkbVlaabaaaaaabIwbVmbVnbVobIwaaabOjbVpbVqbVrbVsbVtbVubVvbXibVwbVxbVybRkbRlccZbVzbVAbVBbVCbVDcblbVEbVFbVGbVHbVIbVIbVIbVIbVJbVKbVLbVMbVMbVNbVNbVObVPbVQeMAbUcbVRbVSbVTbVUeNvbRFbVWeNmeNxeNweNybVZeMkeNzeNAbWbbWceNBeNBeNCeNBeNBeNBeNDeMGbWfbWgbWhbWibWjbWkbWleNrbWmbWnbWobWpbWqbWnbWrbWsbWnbWtbWubKTeMceMcbWvbWwbWxacFbWybWzbWAeNEbWBbWCbWDbWEbWFbWGbWHbWIbWJbWKbWJbWLbWKbWKbWKbWMbWNbWObWPeNFaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaabQZbQZbWRbQXbQXbQXbQXbQXbQXbQXbQXbQXbQXbQXbQZbQZaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabbWSbOjbOjbOjbWTbOjbOjbWUbXibWVbWWbWXbWYbWZcdgbXabXbbXcbXdbXeccZbXfbXgbXhccacepcepcepcepcfyceqcfCeNGbXjeNGeNGbXkbXlbXmbXnbXobXpbXqbXrbXsbXtbXubXvbXwbXxbXybXzbXAbXBbXCbXDbXEbXFbXFbXFbXGbXHbXIbXJbXKeNHeNHbXLeNHeNJeNIeNLeNKeNrbXPbXQbXRbXSbXRbXTbXUbXVbWneMcbXWeMceMcbXXbXYbSbbvqeKIeMtbXZeMteMtbYabYbbYcbYdbYebWKbYfbYgbYhbWDbYhbWDbYibWDbWDeMtbYjbYkbYleNMaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaabQZbQXbQXbQXbQXbQXbQXbYnbQXbYobQXbQXbQXbQXbQXbQZbQZaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWSbYpbYqbYrbOjbYsbXibYtbYubYvbRlbYwcfUbYxbSybYybYzbYAcfUbYBbYCbYDcgYcgYbYEbYFbYGbYHbYIciobYJbDgbYKeMAbYLbDgbDgeNOeNNbYNbYObYPbXsbYQbYRbYSbYTbYUbYVbYWbYXbYYbYVbYVbYZbZabZabZabZbbZabZcbZabZdbZebZfbZgbZhbZibZjbZkbZleNrbZmbZnbZobZpbZobZqbZrbXRbZsbZtbZubvqbZvbvqbXYbSbbvqeKIbZwbZxbZyeMteMteMteMteMtbZzbWDbZAbZBbYibWDbZCbWDbSdbWDbZDeMtbZEbZFbZGeMtaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaabQZbZHbZHbZHbZHbZHbZHbZIbQXbZJbZHbYobQXbQXbQXbQXbQZaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWSbZKbZLbZMbOjbYscjjcjjcjjcjjcjjcjjcblcblcblcblcblcblcblbZNbZObZPbZQbZRbZSbZTbZTbZUbZVciobDgbDgbZWeMAbZXbDgbDgbDgbZYbZZcaabXqcabeNPcacbZacadcaecafbLJcaecagbXFbXFbXFbXFbXFbXFcaebXFbXFbXFbLJcahcaicajcakcalcamcancaoeNrcapcaqbXRcarbXRcascatcaucavcawcaxcaybvqcazbXYbSbcaAeKIbyOcaBcaCcaDcDsbsabsaeMtcaEcaFcaGcaHcaIcaJcaKcaLcaMcaNcaOeMtcaPcaQcaRcaSaacaacaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaacaTbQVbQVbQVbQVbQVbQVbQVcaUbQYbQXbQXbQXbQXcaVbQYbQZaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWSbWSbWSbWSbOjbYsbWSaaaaaaaaaaaacjpcaWcaXcaYcaZcbacbbcikcbccbdcbecbfcbgcbhcbicbicbjcbkckycjWcjWcjWcjWckAcjWbDgbDgbUccbmcbncbocbpcbqcbrcalcbscbtcbucbvcbwcbxcbybXFbXFcbzeNQeNRcbCeNReNQeKQeNSeNTeNTeNUcbEeNVeNpcbFeNWeNrcbHcbIcbJcbKcbLcbMcbNeNreNreKIeNXeKIeKIeKIcbOcbPcbQeKIbsacaBcbRcbScDscDscDseMteMteMteMteMteMteMteMteMteMteMteMteMteMteMteMteMtaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaabQZbVhbVhbVhbVhbVhbVhcbTbQXbVgbVhcbUbQXbQXbQXbQXbQZaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacbVaaaaabaabckBckBckBckBckBckBckBckBbOjbWUclvaaaclCcnjcmFcobccbcccccdcceccfccgeNYcchcciccjcckcclccmccnccoccpccqckyccrccsccsccscctcjWbDgbDgeNZeNZeNZeNZeOaeNZccuccuccveNZeNZeObeNZeOdeOcccxccyccxeOecczccAccBcqAbrebreeOfccCccDccEeOgccFccGbVQeNreNreOheNrccHeNreOjeOieNrccKccLccMbDgccNeOleOkeOneOmeOlbsacaBccPbsaccQccRccSccTbsabsabsabsabsabsaccUccVeLVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabQZbQXbQXbQXbQXbQXbQXbYnbQXcbUbQXbQXbQXbQXbQXbQZbQZaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaccXccYccYccYcovcfAcdacdbcdccddcdecoYcdfbWUcqkaaacqXcdhcdicrccdkccccdlcdmcdncdocikcdpbYCbTWcbfcdqbZTcdrbZTcdscdtcducdvcdwcdwcdwcdxcjWbDgbDgeNZcdycdzcdAcdBcdCcdDcdDcdEcdFcdGcdHcdIcdJeOocdKbXJbXJeOpcdLcdMcdNeOqaaaaaaeOgcdOcdPcdQeOfcdRcdScdTcdUcdUcdVbBDcdWcdXcdYcdZcdXcdXcdXceacdXcdXcebceccedceecefcegcehceibQOcejbQObQObQObQObQOcekcelbQObQOcembsaeOraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabQZbQZbWRbQXbQXbQXbQXbQXbQXbQXbQXbQXbQXbQXbQZbQZaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceocricricricricrjcercescetceuceucevcoYcewbYscqkaaacqXcexceycezceAceBceCceDceAceAceEceFceGceHcCLcCLceIceJbZTceKceLceMcdwcdwcdwcdwceNcjWbDgbDgeNZceOcePceQceRceSceTceTceUceVceWceXceYceZeNZcfabXFcfbeKQcfccdMcfdeOqaaaaaaeOgcfecffcfgeOgbDhcfhcficficficficficficfjcfkcflcfmeOseOseOteOueOseOscfpcfqcfreOweOveOyeOxeOzeOveOveOveOveOAeOBeOzeOveOvbsacfxbsaeMdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeNibQZbQZbZHbZHbQXbQXbQXbQXbQXbQXbQXbQXbQZbQZaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrRcfzcsocfBcsocfEcfDcgQcfFcfFcfGcoYcgTbWUcqkaaacqXcfIcfJctfcfKccccfLcfMcfNcfOcikcdpbYCbYDcfPcgYcfQeOCcfRcfScfTcukcfVcdwcdwcfWcfXcjWbDgcfYeNZcfZcgacgbcgccgccgccgdcgecgccgccgfcgbcggeODcghbXFcgieKQcgjcdMcgkeOqaaaaaaeOgcglcgmcgneOgcgobDgcfYeOEeOEeOEeOEeOEeOFeOHeOGeOEeOIcgpcgqcgrcgseOIeOJcgueOKeOvcgvcgwcgwcgwcgxcgycgzcgAcgBcgCcgDcgEeOvcgFcgGcgHeOLcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgJcgKcgLbQZbSibQZbQXbQXbQXbQXbQXbQXbQXbQZbQZaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaacrRcgMcgNcgOcgPcetchYcetcgRcetcgScuPcgUcigcvjaaacxIcnjcyCcobcgZccccccchachbchceOMchdchechfchgcgYchhchichjchkchlckychmcdwcdwcdwchncjWbDgbDgeONeONeOOchoeOPeOReOQeONeOSeOUeOTchveOVeOOeOWcfabXFcfbeKQchwcdMcdNeOqaaaaaaeOgchxchychzeOgbDgbDgbDgeOEaabaaaaaaaabaaaaabaaaaaaeOIchAchBchCchDchEchFchGchHchIchJchKchLchLchMchNchNchOchPchQchQchReOveOXchSeOYeOXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabQZchTchUchVbQZbQZbQXbQXchWbQXbQXbQZbQZaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrRchXcsochZcsociacibcidciccgQcifcoYcjfbWUbWSaaaaaaaaaaaacjpcihciicijcijcikcilcikcimbYCbTWcineOZcipciqcircircirciscitcdwciucdwcivcjWbDgbDgeONciwcixciycizciAciBeONciAciBcizciCciDciEeOWcghciFcgieKQchwcdMciGeOqeOEeOEeOgeOgeOgeOgeOgciHbDgbDgeOEaabaaaaaaaaaaabaabaabaaaeOIciIciJciJciKciLciMciNciOciPciQciRciSciTciUciVciWchNchNchNciXciYeOvciZcjacjbeOXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaePacjdcjebSjeMMbQZbQZbQXbQYbQXbQZbQZaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOabAcABcABcABcABcABcABcABcABcAIcAIcAIcAIcAIckBcoYcoYcoYcoYcoYcoYcjgeHwcgXcgXcgXcgXcgXcjpcikcikcikcikcikcikcikcjhbYCbTWcjiePbcjkcjlcjmcjncjocAXcjqcjrcjscjtcjucjWbDgbDgeONcjvcjwciycizcizcjxeONcjycizcizciCciycjzeOWeKQeKQeKQePccjAcdMcjBeOqcjCbDgbDgbDgbDgcjDbDgbDgbDgbDgeOEaaaaaaaaaaaaaaaaabaabaaaeOIcjEcjFcjFcjGcjHcjIcjJcjKcjLcjMcjNchNchNchNcjOcjPchNcjQchNciXcjReOvcjScjTcjUeOXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaePdeMJeMJeMLeMMeMMbQZbQZbQZbQZeMNaabaabaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacBRcjXcjYcjZckackackbckcckdckeckfckgckhckickjckjckjckkcklckmckncknckockpckqckrcksckrckrckrckqckrckrcktckuckvckwbYCbTWckxePeckzcCccgYcDEcCLcDGcDFcDJcDIcDLcDKcDNbDgbDgeONckCckDckEckFckGckHeONckIckGckJckKckEckLeOWbDgbDgbDgckMchwcdMchwckNbDgbDgbDgbDgbDgbDgbDgbDgbDgbDgeOEaaaaaaaaaaaaaaaaabaabaabeOIckOckPckPckPePfeOlckQeOmePfckRckSckTckTckUcjMcjMckVckTckWckXckYeOvckZclaclbeOXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacBRcjXclccldclecldclfclgclhclicljclkcllclmclnclnclnclnbYCbTXbTXbTXclncloclnclnclnclnclnclnclnclnclnclnclpclqclrclscltcluePgclwclxcGIclyclzclAclBcHKclDclEclFcHLcficlGePhclHclIclJclKcizclLeONclLcizclKclMciyclNeOWclOePiePiePjclPclQclReOqePkeOHeOHePleOEeOEeOEeOFeOHeOGeOEaaaaaaaaaaaaaaaaaaaabaabeOIclSclTclUclVeOlclWclXclYeOlclZcmacmacmacmbcmccmdcmecmacmacmacmfeOvePmcmgePoePnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacBRcmicldcmjcmkcmlcmmcmncmocmpcmqcmrcmscmtcmucmvcmwcmwcmxccacmyccacmucmzcmucmucmucmucmucmucmucmucmucmucmAclncmBcmCcmDcmEcHPcmGcmHcmIcmJcmKcmLcmMcmNcmOcmPcmQcDIbXlcmRePpcmTcizciycizcizcmUePqcmVcizcizciCciycmWeOWcmXeOEaaaePreOqcmYeOqeOqaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeOleOleOleOleOleOleOleOleOlcmZcnacnbeOleOvePtePsePueOveOveOveOvePtePsePueOveOvePvcnfePvaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOabAcABcABcABcABcABcABcABcABcABcABcABcABcABcgXcngcolcolcnhcolcnicolcolcIdcIecolcolcIfcIgcIecolcolcolcolcnkcnlcnmcnncnocnpcnqcnrcnscnrcnrcntcnrcnucnvcnwcnxcnycDNbDgcmXePwcnzcnAcnBcnCcnDcnEeONcnFcnDcnGciCcnHcnIeOWcmXeOEaaaePrcnJcnKcnLeOqaaaaaaaaaaaacnMaaaaaaaaaaaaaaaaaaaaaaaacnMaaaaaaeOlcnNcnOcnPePxcnRcnScnTePycnUcnVcnWePzcnXaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaabePAcnYePAaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuacuacuakqakqacuakqakqakqakUakqakqakqakUcnZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacIqcoacIucoccodcoecofcogcohcoicojcokcolcojcomconcoocoocopcolcoqcorcoscotbTWcoucIBcowcoxcoycozcoycoAcoBcoCcoDcoEcoFcDNcDNcmXePweOWeOWcoGeOWeOWePBePDePCePCePCcoHePCePEePCcoIeOEaaaePrcoJcnKcoKeOqePGePFePFePHeOqeOqePJePIePIePKePIePIePKePLaaaaaaeOlcoPcoQcoPcoRcoScoTcoUePyePMcoVePMeOleOlaaaaaaaaaaabaabaaaaagaaaaaaaaaaaaaabaaacoWaaaaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaaaaaaaacuaaaaaaaabaabaaaaabaabaaaaaaaabaabaabaaacnZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacIOcoacIQcoZcpacpbcpccpccpccpccpdcpecpfcoocpgcoocoocphcoocpicpjcpkcplcotbTWcpmePNcpncoxcpocppcpqcoxcprcpscptcpucpvcpwcpxcpycpzcpAcpAcpBcpCcpDcpEcpFbXlbXlbXlcpGbDgbDgbVPbDgeOEaaaePrcpHcnKcpIePOcpJcpKcpLcpMcpNcpOcpPcpNcpOcpQcpNcpRcpSePPaaaaaaeOlcoPcoPcoPePQcpUcnScpVcpWcpXcpYcpZcqaeOlaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaabaaacqbaaaaabaabaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaaaaacuaaacqccqdcqeaaacqccqdcqeaaacqccqdcqeaabcqfaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacIOcoacIQcqgcoocphcqhcoocoocoocqicoocqgcqgcoocoocoocoocqjcIScpjcqlclncqmbTWePNePNcqncoxcqocqpcqqcoxcqrcHKcqscqtcqucqvcITbVQbDgcqwbVQcqwbDgbDgbDgcmXbDgeOEeOFeOHeOHeOHeOGeOEeOEaaaePRcqycqzcqAePScqCchwchwcqDcqEcqFcqGcqEcqFcqGcqEcqFcqGePPaaaaabeOlePyePyePyePycqHcoTcqIcqJcqKcqLcqMcqNeOlaaaaaaaaaaaaaaacqOcqOcqOcnZaabaabaabaabcqPaabaabaabaabaabakUcqOcqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaacuaaacqccqQcqeaaacqccqQcqeaaacqccqQcqeaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabcIOcoacIUcqgcqRcoocqScqTcqUcqUcpgcoocqgcqVcoocoocoocoocqWcIVcqYcqZbSCcracrbePTcrdcrecoxcqocrfcrgcoxcrhcHKcDNcIXcDIcIZcIYcJfcJacJucJjcJCcJacJacJacJDcJaeOEaaaaaaaaaaaaaaaaaaaabaaaePrcrlcnKcrmePUcrnchwchwcqDcrocrpcrqcrrcrpcrqcrrcrpcrsePPaabaabeOlcnNcnOcnPePVcrucnScrvcrwcrxcrycrzcrAeOlaaaaaaaaaaaaaaacqOaaaaabaaaaabaaaaaaaaacrBaaaaabaabaaaaaaaaaaaacqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaagaaaaaaaaaakqaabcqccqQcqeaaacqccqQcqeaabcqccqQcqeaabaaaaaaaabaaaaaaaaaaabaaaaaaaaaaaaaaaaabaaaaaacJEcoacolcrCcoocrDcrEcrFcrGcrHcrGcrIcrGcrJcrKcojcrLcqgcqgcIScrMcrNcrOcrPcrQePWcrScrTcrUcrVcrWcrXcrYcrZcJXcsacsbcsccsdcsecsfcsgcshcsicsjcskcslcsmcsncKaaabaaaaaaaaaaaaaaaaaaaabaabePRcspcsqcsrcsscstchwchwchwcsuchwchwchwchwchwchwchwcsvePXaaaaaaeOlcoPcoPcoPcsxcoScoTcsycszcsAcsBcsCcsDeOleOleOleOlaaaaaacqOaaacsEcsEcsEcsEcsEaabcsFaabcsEcsEcsEcsEcsEaaacqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaaabaaacqccqQcqeaabcqccqQcqeaaacqccqQcqeaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaabaaaaabaabaaaaaacKncsGcolcsHcsIcsIcsJcolcolcolcolcolcolcolcolcolcolcolcolcolcbWcsKcbWcKrcbWcgXcsLcsMcsNcsOcsPcsQcsRcsScJXcsTcsbcsccsUcsVcsWcsXcsYcsZctactbctcctdctecKvaabctgctgctgctgctgaaaaaaaabePrcthcnKctictjctkctlchwchwctmchwchwchwchwchwctnchwctoePZaaaaaaeOlcoPcoPcoPePVctqcnSctrctscttctuctvctwctxctyctzeOlaaaaaacqOaabctActBctBctBctBctCctDctEctFctFctFctFctGaabcqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaacuacuakqaabaaacqccqQcqeaabcqccqQcqeaaacqccqQcqeaabaaaaaaaaaaaaaaaaaaaaaaaaaabcKzcKwcKwcKwcKwcKncKncoacolctHctIctIctJeImctKctLctLctLctLctMctNctOctNctNctPctPctNctQeIoeIneIpeIpctRctSctTctUctVctWctWctXeIqctYctZcuacubcsVcuccsXcudcuecufcugcuhcuicujeIrculcumcuncuocupctgaaaaaacuqeQaeQbcureQceQbcuscutcuucuvcuycuwcuxcuycuzcuAcuBcuCcuDePPaaaaaaeOlePyePyePyePycuEcoTcsycuFcuGcuHcsCcoTcuIcoTcuJeOlaaaaaacqOaabcuKcuKcuKcuKcuKaaacsFaaacuKcuKcuKcuKcuKaabcqOaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaacuaaaaabaaaaabaabcuLaabaabaabcuLaabaaaaabcuLaabaaaaaaaaaaaaaaaaaaaaaaaaeIteIseIucuMcuNcuOeIvcuQcuRcuScolcolcuTcuUcolcolcuVcHqcHqcHqcHqeIweIyeIxeIyeIyeIyeIpeIpeIzeIAcuWcuXcuYctWcuZctTctWctWctWctWcvacJXcvbcvccubcubcsVcuccvdcudcuecvecvfcvgcvhcvieIBaabcvkcvlcupcvmctgaaaaaaaaaeQacvncvocvpeQbcvqcvrcvscvtcvucqGcqFcvucvvcvwcvxcqGcqFePPaaaaaaeOlcnNcnOcnPeQdcrucnScvzcvAcvBcvCcvDcvEcvFcvGcvHeOlaabaabcqOaaaaabaaaaabaabaabaaacsFaaaaabaaaaabaaaaabaaacqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaakqaabcvIcvJcvJcvKcvLcvMcvMcvMcvLcvMcvMcvMcvLcvMcvMcvNcvJcvJcvJcvJcvJcvOcvPcvQcvRcvScvTcvUcvVcvWbYrcoacvXcolcolcolcolcvYcuVcHqcvZcwacwbcwccwdcwecwfcwgcwhcwicwjcwkcwlcwmcwncwocwpcwqctTcwrctWctWctWcwscJXcwtcwucubcwvcwwcwxcwycwzcwAcwBcwCcwDcwEcwFeIrcwGcumcwHcupcupctgaaaaaaaabeQacwIcvocwJeQbcwKcwLctlcwMcvucwNcwOcvucwPcwQcvxcwNcwRePPaaaaaaeOlcoPcoQcoPcwScoScoTcwTcvAcwUcwVcoTcwWePyePyePyeOlaaaaaacqOaaacsEcsEcsEcsEcsEaabcsFaabcsEcsEcsEcsEcsEaabcqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaacuaaaaabaaaaabaabcwXaabaaaaabcwXaabaaaaabcwXaabaaaaaaaaaaaaaaaaaaaaaaaaeIteIseICcwYcwZcxacKwcxbbYrcxccuRcuRcuRcuRcxdcuRcvWcHqcxecxfcxgcxhcxicxjcxkcxlcxmcxncxocxpcxqcxrcxscxtcxuctSctTcxvcxwctWctWcxxcJXcxycxzcubcxAcsVcxBeIDcxCcxDcxEcxFcxGcxHcxGeIEaabctgctgctgctgctgaabaabaabeQecxJcvocwJeQbcxKcxLcxMcxNeQgeQfeQheQhcxPeQheQjeQieQbeQkaaaaaaeOlcoPcoPcoPeQdcxRcxScxTcqMcxUctwctwctwcxVcxWcxXeQlaaaaaacqOaabctActBctBctBctBctCctDctEctFctFctFctFcxZaabcqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaacuacuakqaabaabcqccyacqeaaacqccyacqeaaacqccyacqeaabaaaaaaaaaaaaaaaaaaaaaaabaabeIFcKwcKwcKwcKweIGcfHcybbYrcycbYrbYrcuVcydbYrcHqcyecyfcygcyhcyicyjcykcylcymcyncyocypcyqcyrcyscytcyucyvcywcyxcyycyzcyAcyBeIHcyDcwxcyEcyFcyGcyHcyIcyJcyKcyLcyMcyNcyOcyPeIIculcumcyQcyRcyRctgaaaaaaaabeQacyScvocyTeQbcyUcyVcyVcyWeQbcyXcyYcyZczaczbczcczdczaeQmaaacuqeOleOleOleOleOlczecoTczfcnSczgcnSczhcnSczicnSczjeQnaaaaaacqOaabcuKcuKcuKcuKcuKaaacsFaabcuKcuKcuKcuKcuKaaacqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaaaaaaacqccyacqeaabcqccyacqeaaacqccyacqeaaaaaaaaaaabaaaaaaaaaaaaaabaabaabaaaaaaaabaabczlczlczlczlczlczlczlczmczlczlcHqcznczocxgcxgczpczqczrczsczteIpczuczvcwmczwczxeIpczyctWczzczAczBczCcyAczDeIJczFczGczHczIczJczGczKczLczMczNcubczOczPczQeIKaabcvkczRczSczTctgaaaaaaaaaeQaeQbczUeQoeQbczVczWczXczYczZcvocAacAbczacAccAdcAecAfeQpaabaaaaaaaaaaaaaaaeOlcAhcAicAjcAkcAlcAmcAncAocAlcAmcApeOlaaaaabcnZaaaaabaaaaabaaaaabaaacAqaaaaabaaaaabaabaabaabcqOaaaaaaaaaaaaaaaaaaaaaaaacAraaaaaaaaacAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMIaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaakqaabcqccyacqeaaacqccyacqeaaacqccyacqeaabaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaabaabaabczlcAscAscAtcAucAvcAvcAwcAxcAycAzcygcyhcxgcxgcxgcAAcxgcxgcxgeIpeILcACcADcAEcAFeIMeINcAHeIOcAJcAKcALeIQeIPeIRcANcAOcAPcxAcsVcAQcARcAScATcAUcubczOcAVcAWeIScAYcumcAZcyRcyRctgaabaaaaaaeQecBacBbcBccBdcBecBfcBecBecBgcBhcBicBjcBjcBkcBlcBmcBneQqaabaabaaaaaaaaaaaaeOlcBpcBqcBrePycBscBtcBuePycBvcBwcBxeOlaaaaaacqOaaacsEcsEcsEcsEcsEaabcqPaabcsEcsEcsEcsEcsEaabcqOaaaaaaaaaaaaaaaaaaaaaaaacArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaakqaabcqccyacqeaaacqccyacqeaabcqccyacqeaabaabaabaaaaabaaaaaaaabaabaaaaaaaaaaabaaaaaaczlcAscAscAtcBycBycBycBzcBzcBAcHqcBBcBCcBDcBEcBFcBGcBHcBIcBIcBIcBJcBKcxgcxgcxgcBLcBMcBNeITcBOcBPcBQeIVeIUcHqeIWeIWcBTcxAcsVcBUcBVcBWcBXcBYcubcBZcCacCbeIXcCdctgctgctgctgctgaaaaaaaaaeQacCecCfcCgcChcCicCjcCicCicCkcClcCmcCncBncCocCpcAeczaeQraabaabaaaaaaaaaaaaeOlcCrcoPcoPePycCscoPcoPePycCscoPcoPeOlaaaaaacqOaabctActBctBctBctBcCtcCucCtctFctFctFctFcxZaabcqOaaacAraaaaaacAraaaaaacArcArcArcArcArcArcAraaaaaacAraaaaaacAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaakUaabcqccCvcqeaaacqccCvcqeaaacqccCvcqeaabakqaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaabczlcCwcCxcBycBycBycCyeIYeIYeIZeIYeIYeIYeIYcCzcCAcCBcCCcCDcCDcCDcCEcCFcCGcCDcCDcCDcCFcCHcCIcCJcBPcCKeJaeIUcCMcCNeJbcCOcCPcCQcCRcCScAUcCTcCUcCVcCWcCXcCYeIIcCZcumcDacDbcDbctgaaaaaaaaaeQacDccDdcDecDfcDgcDhcDiczacDjcDkcDlcDmcDncDocDpcDqcDreQsaaaaaaaaaaaaaaaaaaeOlcDtcoPcoPePycDucoPcoPePycDucoPcoPeOlaaaaaacqOaabcuKcuKcuKcuKcuKaaacqPaaacuKcuKcuKcuKcuKaaacqOaaacArcArcArcAraaacArcArcArcArcArcArcArcArcAraaacArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaakqaaaaabaaaaaaaaaaabaabaabaaaaaaaabaabaaaakqaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaabczlcBycBycBycBycBycByeIYcDvcDwcDxcDycDzeIYcDAcDBcDCczocxgcxgcDDeJdeJceJecDHeJgeJfeJhcHqeJicCJcBPcDMeJjeIUcHqcDOeIWcDPcDQcubcCRcCScDRcubcCUcCVczOczPcDSeIKcDTcvkcDUcDVcDWctgaaaaaaaaaeQteQveQueQueQweQxeQxeQycEacEbcEccEdcEccEeeQzeQzeQkeQAeQzaaaaaaaaaaaaaaaaaaeOlcoPcoPcoPePycEfcoPcoPePycEfcoPcoPeOlaaaaabcqOaaaaaaaabaabaabaaaaaacqPaabaaaaaaaabaabaaaaaacqOaaacArcArcArcAraaacArcArcArcArcArcArcArcArcAraaacArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaacuacuakqacuacuakUakqakqakqakqacuakqakqacucEgaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaczlcEhcBzcEicEjcEkcEleIYcEmcEncEocEpcEqcErcEscEtcEuczocxgcEvcEweJkcExcEycEzcEAcEBeJlcECcDCczocEDcEEeITeJmcHqeJneIWcEGcEHcubcCRcCScAUcubcEIcCVczOcEJcEKeIScELcumcEMcDbcDbctgaaaaaaaaacENaaaaaaaaaaaaaaaaaaeQacEOczaczacEPcEQcEReQzaaccEScETcEUaaaaaaaaaaaaaaaaaaeOleOleOleOleOleOleOleOleOlcEVcEVcEVeOlaaaaaacqOcqOcqOcqOcqOaaaaaaaaacqPaaaaaaaaacqOcqOcqOcnZcqOaaacArcArcArcAraaacArcArcArcArcArcArcArcArcAraaacArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoXcoXcoXcoXcoXcoXcoXcoXcoXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabczlczlczlcEWcEXcEYcEZeIYcFacFbcFccFccFdcFecCDcFfcFgcFhcFicFjcFjcFkcFlcFmcFncFocFpcFkcFqcFrcFscFtcxgcFucFvcFwcDOeIWcFxcFycubcCRcubcFzcubcCUcCVczOczPcFAeIKcDTctgctgctgctgctgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeQacFBczaczaczYcFCcFDeQzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacENaaaaaaaaaaaaaaaaaaaaaaaaaacaacaacaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaabcFFaabcqOaaaaaaaaaaaaaaaaaaaaacArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabcFGcFHcFIcFJaabaabeIYcFKcFLcFccFccFMeIYcFNcFOcFPcFQcFRcFScFTcHqcFUcFVcFWcxgcFXcHqcFYcFZcGacFQcFQcGbcGccHqcGdeIWcGecGfcubcCRcubcBUcBVcGgcGhcCWcGicGjeIIcGkcumcGlcGmcGmctgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeQtcGncGocGpcGqcGrcGseQzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaaaaabaaacqOaaaaaaaaaaaaaaaaaaaaacArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabcFGcGtcGucGvaabaaaeIYcGwcFLcFccFccGxeIYcGycGzcHqcGAcGBcGBcGBcHqcGCcGDcGEcGFcGGcHqcGBcGBcGBcGAcHqcGHcGycHqcDOeIWcGJcGKcGLcGMcGNcGOcGPcGQcyNcGRczPcGSeIKcDTcvkcGTcGUcGVctgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeQzeQBeQCeQCeQCeQCeQDeQzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOcqOcqOcqOcqOaaaaaaaaaaaaaaaaaaaaacArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYaaaaaaaaacGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcFGcGZcHacFGcHbaaaeIYcHccHdcFccFccHeeIYcHfcHgcHqcHhcHicHjcHkeJocHlcHmcHncHocGGeJocHicHicHicHpcHqcHrcHscHqcDOcHtcHucHvcHwcGPcHxcHycHzcHAcHBcHCcHDcHEeIScELcumcHFcGmcGmctgaabaabaaaaaaaaaaaaaaaaaaaaaaaacENaaaaaaaaaaaaaaaaaacENaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacHGcHGcHGcHGcHGcHGcHGeIYcHHcFbcFccFccHIeIYcCMcHJcHqcHqeJpeJreJqeJscHMcFQcHNcFQcHOeJteJqeJreJucHqcHqcHQcHRcHqcDOeIWcHScHTcHwcHUctZcubcubcHVczKcHUczPcHWeIKcDTctgctgctgctgctgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYaaaaaacGYaaaaaacGYcGYcGYcGYcGYcGYcGYaaaaaacGYaaaaaacGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacHGcHGcHGcHGcHGcHGcHGeIYcHXcHYcFccFccHZeIYcHqcIacHqcIbcIccIceJveJxeJweJweJweJweJweJxeJycIccIccIhcHqcIicHqcHqcDOeIWcIjcGLcIkcIlcImcIncIocIlcIocIlcIpcGPeJzcDTaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYaaacGYcGYcGYcGYcGYcGYcGYcGYcGYaaacGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacHGcHGcHGcHGcHGcHGcHGeIYcIrcIscFccFccIteIYeJAcIvcIwcIxaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaabaaaaaacIycIzcIAeJBcHqcICeJbcIDcIEcIFcIGcIHcIIcIJcIKcubcILcIMcINeJCcDTaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacArcArcArcAraaaaaacArcArcArcArcArcArcAraaaaaacArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYaaacGYcGYcGYcGYcGYcGYcGYcGYcGYaaacGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacHGcHGcHGcHGcHGcHGcHGeIYcHHcFbcFccFccIPeIYeJDcIRcIRaaaaaaaabaabaabaabaabaabaabaabaabaabaabaaaaaacIRcIReJDcHqcCMeIWeJEeJGeJFeJIeJHeJKeJJeJIeJJeJLeJJeJLeJMcDTaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaacArcArcArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYaaacGYcGYcGYcGYcGYcGYcGYcGYcGYaaacGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacHGcHGcHGcHGcHGcHGcHGeIYcJccJdcFccFccJeeIYeJNcJgcIRaabaabaabcJhaaaaaaaaaaaacJhaaaaaacJhaabaabaabcIRcJieJOcHqcCMcHqaabcJkaabcJlcJmcJncJocJpcJocJqcJocJqcJrcJsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacArcArcArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeIYcJtcJdcFccFccIPeIYeJPcIRcJvaaaaaaaabaaaaaaaaaaaaaaacJwaaaaaaaaaaabaaaaaacIRcIReJPcHqcCMcHqctgcJxcvkcJxctgcJxcvkcJxctgcJycvkcJzctgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacArcArcArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeIYcJAcFbcFccFccJBeIYeJQeJRcIRaaaaaaaabaaaaaaaabaabaabaabaabaaaaaaaabaaaaaacIReJTeJScHqcJGcHqctgcJHcJIcJJctgcJKcJLcJMctgcJNcJOcJPctgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacArcArcArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceIYeIYeIYeIYeIYeIYeIYcHqeJDcIRaaaaaaaabcJhaabaabaacaacaacaabcJQaaaaabaaaaaacIReJDcHqcHqcCMcHqctgcJRcJScJRctgcJTcJUcJTctgcJVcJWcJVctgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacArcArcArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaacaabaacaacaabaabaabacuacucHqcHqeJUcIRaaaaaaaabaaaaaaaabcJYcJZaacaabaaaaaaaabaaaaaacIReJVcHqcHqcCMcHqctgcJRcKbcJRctgcJTcKccJTctgcJVcKdcJVctgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacArcArcArcArcAraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaabaabaaaaaaaabaabacucHqcHqeJDcIRaaaaaaaabaaacKeaabaacaacaacaabaabcJhaabaaaaaacIReJDcHqcHqcCMcHqctgctgctgctgctgctgctgctgctgctgctgctgctgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabcHqeJTeJScIRaaaaaaaabaaaaaaaabaabaabaabaabaaaaaaaabaaaaaacIReJQeJRcHqcJGcHqcHqcHqcHqcHqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaacGYcGYcGYcGYaaaaaacGYcGYcGYcGYcGYcGYcGYaaaaaacGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaabcHqeJPcIRcKgaaaaaacKhaaaaaaaaaaabaaaaaaaaaaaaaaaaabaaaaaacIRcIReJPcHqcCMeJWcKicKjcKkcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcHqeJXcKocIRaabaabaabcJhaaaaaacJhaaaaaaaaaaaacJhaabcKpaabcIRcKqeJYcHqcCMcKscxgcxgcKtcKuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacHqeJZeKacKxaaaaaaaabaabaabaabaabaabaabaabaabaabaabaaaaaacKyeKaeKbcHqcCMcHqcKAcKBcKtcKCaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeJdcHqeIQcIycKxaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaabaaaaaacKycIxeIQcHqcHqcCMcHqcHqcHqcKDcHqaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaacHqcHqcIycIccIccIccIccIccIccIccIccIccIccIccIccIccIxcHqcHqcHqcHqcJGcHqaaaaabcKEcKFaabaaaaaaaaaaabaaaaaaaaaaabaaaaaaaaaaabaaaaaaaaaaabaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaacHqcHqcHqcHqcHqcHqcHqcHqcHqcHqcHqcHqcHqcHqcHqcHqcHqaaacHqcHqcKGcHqaabaabcKHcKIcKJcKKcKKcKKcKJcKKcKKcKKcKJcKKcKKcKKcKJcKKcKKcKLcKMaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGYcGYcGYcGYcGYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacHqcHqcKNcHqcHqcHqcHqaaaaabaaaaaaaaaaabaaaaaaaaaaabaaaaaaaaaaabaaaaaacKHcKOcKFaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacHqcCMcCMcKPcKQcKQcKRaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabcKScKOcKMaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacHqcJGcCMcKTcKUcKVcKWaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaacKHcKOcKFaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcJbcJbcJbcJbcJbcJbcJbcJbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacHqcKXcCMcKYcKQcKQcKZaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaacKScLacKFaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeJdcHqcHqcHqcHqcHqcHqaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaabcKScLbaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaabdiZcLcdiZcLdcLedjadjadjadjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabdiZcLfcLgcLhcLidjbcLjcLkdjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaabdiZcLfcLlcLmcLmcLncLocLpdjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaabdiZcLqcLrcLmcLmcLscLtcLudjaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabdiZdiZdjlcLmcLmdjadjmdjadjaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaofaofaaaaabaaacLvcLwcLmcLmcLxcLycLvaabaabaabaofaofaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuacucLzcLzacuacuaaacLAcLBcLCcLDcLEcLFcLAaaaacuacucLzcLzacuacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcLHcLIcLJacuacucLKcLLcLMcLNcLmcLOcLKacuacucLPcLQcLRcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfaaacKfcKfcKfcKfcKfaaacKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcLHcLRcLUcLVaaqaaqaaJcLWaaqcLXaosaaqaaqcLVcLYcLHcLRcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmaaacKmcKmcKmcKmcKmaaacKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfaaacKfcKfcKfcKfcKfaaacKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcLHcLRcLUcLVdjpdjpdjAcLWdjpcLXdjBdjpdjpcLVcLYcLHcLRcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmaaacKmcKmcKmcKmcKmaaacKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfaaacKfcKfcKfcKfcKfaaacKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcLZcMacMbcMbcMccMdcMecMfcMgcMgcMhcMicMjcMkcMkcMlcMmcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmaaacKmcKmcKmcKmcKmaaacKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncMocMpcMpaaqcMqcMrcMrcMscMrcMrcMtaaqcMpcMpcMucMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncLSaaaaaaaaqcMwcMxcMycMzcMAcMBcMCaaqaaaaaacLGcMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMDaaqaaqaaqaaqcMEcMFcMrcMrcMGcMHcMIaaqaaqaaqaaqcMJcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncLSaaaaaaaaiafaaaiaiVcMKaaiaaiabmaaiaaaaaacLGcMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncLSaaaaaaaaicMLcMMcMNcMOcMPcMQcMRaaiaaaaaacLGcMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncLSaaaaaiaaicMScMQbjjbjjbjjcMQcMTaaiaaiaaacLGcMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncLSaaaaaiaaicMUbjjbjjcMVbjjbjjcMWaaiaaiaaacLGcMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMXaaqaaqaaiaaicMQbjjcMYcMYcMYbjjcMQaaiaaiaaqaaqcMZcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncLSaaiaaicNacMQcNbcMYcNccMYcNbcMQcNdaaiaaicLGcMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncLSaaaaaiaaicMQbjjcNecNfcNgbjjcMQaaiaaicLVcNhcMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncLSaaaaaiaaicMUbjjbjjcNibjjbjjcMWaaiaaicNjcNkcMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncLSaaaaaiaaicNlcNmcNncNocNpcNqcNlaaiaaicNrcNscNtcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcNuaaqaaqaaqaaiaaiaaiaaicNvaaiaaiaaiaaiaaqaaqaaqcNwcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncLSaaaaaaaaaaaiaaiaaicNxaaiaaiaaiaaaaaaaaacLGcMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncLSaaaaabaaaaaqcNycNzbXicNAcNBaaqaaaaaaaaacLGcMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncNCcLVcNDcNDaaqcNEcNFcNGcNHcNIaaqcLVcLVcLVcNhcMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaacKfcKfcKfcKfcKfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncMocMpcMpdjpcMqcMrcMrcMscMrcMrcMtdjpcMpcMpcMucMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaacKmcKmcKmcKmcKmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncLSaaaaaadjpcMwcMxcMycMzcMAcMBcMCdjpaaaaaacLGcMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMDdjCdjCdjCdjpcMEcMFcMrcMrcMGcMHcMIdjpdjCdjCdjCcMJcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncLSaaaaaadjEdjDdjEdjLcMKdjEdjEdjMdjEaaaaaacLGcMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncLSaaaaaadjEcMLcMMcMNcMOcMPcMQcMRdjEaaaaaacLGcMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncLSaaadjEdjEcMScMQbjjbjjbjjcMQcMTdjEdjEaaacLGcMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncLSaaadjEdjEcMUbjjbjjcMVbjjbjjcMWdjEdjEaaacLGcMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMXdjCdjCdjEdjEcMQbjjcMYcMYcMYbjjcMQdjEdjEdjCdjCcMZcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncLSdjTdjEcNacMQcNbcMYcNccMYcNbcMQcNddjEdjTcLGcMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncLSaaadjEdjEcMQbjjcNecNfcNgbjjcMQdjEdjEcLVcNhcMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncLSaaadjEdjEcMUbjjbjjcNibjjbjjcMWdjEdjEcNjcNkcMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncLSaaadjEdjEcNlcNmcNncNocNpcNqcNldjEdjEcNrcNscNtcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcNudjCdjCcMYdjEdjEdjEdjEcNvdjEdjEdjEdjEcMYdjCdjCcNwcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncLSaaaaaaaaadjUdjUdjUdkedjUdjUdjUaaaaaaaaacLGcMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncLSaaaaabaaadkfcNycNzdkqcNAcNBdkfaaaaaaaaacLGcMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcMncNCcLVcNDcNDdkfcNEcNFcNGcNHcNIdkfcLVcLVcLVcNhcMvcLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacucLGcNJcMbcMbcMbcMbcNKcNLcNMcNNcNOcNPcNQcNRcMkcMkcMkcNScLSacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTaaacLTcLTcLTcLTcLTaaacLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaaacMpcMpcMpcMpcMpaaqcNTcNUcNVcNWcNXabZcNYcMpcMpcNZcNZaaaacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTaaacLTcLTcLTcLTcLTaaacLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuacuacuacuacuacuacuaaqcOacObcOccOdcOeaaqacuacuacuacuacuacuacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaqaaqcOfcOgcOhaaqaaqaaaaaaaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTaaacLTcLTcLTcLTcLTaaacLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuaaacMpcMpcMpcMpcMpdkfcNTcNUcNVcNWcNXdkrcNYcMpcMpcNZcNZaaaacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTaaacLTcLTcLTcLTcLTaaacLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuacuacuacuacuacuacudkfcOacObcOccOdcOedkfacuacuacuacuacuacuacuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaacLTcLTcLTcLTcLTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabdkfdkfcOfcOgcOhdkfdkfaaaaaaaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -12817,19 +13293,19 @@ cOlcPfcPdcPncPecPjcPhcPacPlcPmcPbcPicOZcPkcPgcPccPhcPjcPbcPdcPncPacPicPecPkcPmcO cOtcPecPmcOZcPacPgcPdcPhcPbcPjcPkcPlcPccPncPicPfcPdcPgcPkcPmcOZcPhcPlcPacPncPjcOocPtcPucOxcOycOzcOAcOBcORcODcPocPpcPqcPrcPvcPscPtcPucOAcOBcOCcODcOBcOCcODcPocPpcPqcPrcPvcPscPtcOLcOTcOUcPecPmcOZcPacPgcPdcPhcPbcPjcPkcPlcPccPncPicPfcPdcPgcPkcPmcOZcPhcOUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacPwcPxcPxcPYcPZcPxcPzcQacQacQacQacQacPzcQbcQbcQbcQbcQccPzcPEcPEcPEcPEcPEcPzcPFcPFcPFcPFcPFcPzcPGcPGcPGcPGcPGcPzcPScPTcPTcPTcPUcPK cOwcPacPjcPccPhcPicPmcPdcPkcPgcPncQdcQecQfcQdcQdcPmcPicPncPjcPccPdcPbcPhcOZcPgcOkcPocPpcPqcPrcPvcPscPtcOLcOxcOycOzcOAcOBcOCcODcPocPpcPqcPrcPvcPscPtcPucOxcOycOzcOAcOBcOCcODcPocOFcOTcOUcPacPjcPccPhcPicPmcPdcPkcPgcPncPbcPfcOZcPlcPecPmcPicPncPjcPccPdcOUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgcQgcQgcQgcQgcQgcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacPwcQhcPxcPxcPxcPxcPzcQicQjcQkcQjcQlcPzcQmcQncQocQpcQmcPzcPEcPEcPQcPEcPEcPzcPFcPFcPFcPFcPFcPzcPGcPGcPGcPGcPGcPzcPScPTcPTcPTcPUcPK cOjcPhcPgcPfcPdcPlcPjcPmcPncPicQqcQecQrcQscQtcQucQdcPlcOZcPgcPfcPmcPkcPdcPccPicOqcOzcOAcOBcOCcODcPocPpcOGcPrcPvcPscPtcPucOxcOycOzcOAcOxcOycOzcOAcPpcPqcPrcPvcPscPtcPucOxcOycOzcOPcOTcOUcPhcPgcPfcPdcPlcPjcPmcPncPicOZcPkcPecPccPbcPfcPjcPlcOZcPgcPfcPmcOUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgcQgcQwcQxcQycQzcQwcQgcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacPwcPxcQhcPxcPxcQAcPzcQBcQjcQkcQjcQCcPzcQmcQDcQEcQFcQmcPzcPEcPEcPQcPEcPEcPzcPFcPFcPFcPFcPFcPzcPGcPGcPGcPGcPGcPzcQGcPTcPTcPTcQHcPK -cOmcPdcPicPecPmcPbcPgcPjcOZcQIcQJcQrcQscQtcQKcQKcQLcQMcPccPicPecPjcPncPmcPfcPlcOncPvcPscPtcPucOxcOycOzcOPcOBcOCcODcPocPpcPqcPrcPvcQNcQOcQPcQQcQRcQScOAcOBcOCcODcPocPpcPqcPrcPvcOJcOTcOUcPdcPicPecPmcPbcPgcPjcQqcQIcQTcQUcQVcQWcQXcPhcPgcPbcPccPicPecPjcOUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQYcQZcRacQvcQZcRbcQvcQZcRccQvcRdcRecQvcQZcRbcQvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgcQgcQwcQwcRfcRgcRhcQwcQwcQgcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacPwcPxcPLcQhcPxcPYcPzcQacQacQacQacQacPzcRicQDcQEcQFcRicPzcPEcPEcPEcPEcPEcPzcPFcPFcPFcPFcPFcPzcPGcPGcPGcPGcPGcPzcQGcPTcPTcPTcQHcPK +cOmcPdcPicPecPmcPbcPgcPjcOZcQIcQJcQrcQscQtcQKcQKcQLcQMcPccPicPecPjcPncPmcPfcPlcOncPvcPscPtcPucOxcOycOzcOPcOBcOCcODcPocPpcPqcPrcPvcQNcQOcQPcQQcQRcQScOAcOBcOCcODcPocPpcPqcPrcPvcOJcOTcOUcPdcPicPecPmcPbcPgcPjcQqcQIcQTcQUcQVcQWcQXcPhcPgcPbcPccPicPecPjcOUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQYcQZcRacQvcQZcRbcQvcQZcRccQvcRdcRecQvcQZcRbcQvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgcQgcQwcQwbDWcRgcRhcQwcQwcQgcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacPwcPxcPLcQhcPxcPYcPzcQacQacQacQacQacPzcRicQDcQEcQFcRicPzcPEcPEcPEcPEcPEcPzcPFcPFcPFcPFcPFcPzcPGcPGcPGcPGcPGcPzcQGcPTcPTcPTcQHcPK cOpcPmcPlcPacPjcPkcPicPgcPccRjcRkcRkcRlcRmcQrcRncRncQMcPfcPlcPacPgcOZcPjcPecPbcOvcPucOxcOycOzcOAcOBcOCcOScPocPpcPqcPrcPvcPscPtcPucQPcRocRpcRqcRrcRscODcPocPpcPqcPrcPvcPscPtcPucOMcOTcOUcPmcPlcPacPjcPkcPicQLcQMcRtcRtcRtcRtcRtcQUcRucPicPkcPfcPlcPacPgcOUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQvcRvcRwcQvcRvcRecQvcRvcRxcQvcRvcRbcQvcRvcRacQvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgcQwcQwcRhcRhcRycRhcRhcQwcQwcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacPwcPxcPxcPxcQhcPxcPzcRzcRAcRzcRAcRzcPzcRBcQDcQEcQFcRBcPzcPEcPEcPEcPEcPEcPzcPFcPFcPFcPFcPFcPzcPGcPGcPGcPGcPGcPzcQGcPTcPTcPTcQHcPK cOocPjcPbcPhcPgcPncPlcPicPfcRCcRlcRlcRDcREcRFcQscQscRGcPecPbcPhcPicPccPgcPacPkcOscPqcPrcPvcPscPtcPucOxcONcOzcOAcOBcOCcODcPocPpcPqcRHcRIcRJcRKcRocRLcOycOzcOAcOBcOCcODcPocPpcPqcOHcOTcOUcPjcPbcPhcPgcPncQIcQMcRtcRtcRtcRtcRtcRtcRtcRMcQIcPmcPecPbcPhcPicOUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgcQwcRhcRhcRhcRhcRhcRhcRhcQwcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacPwcPxcRNcPxcPxcQhcPzcPNcPOcPNcPOcPNcPzcRBcQDcQEcQFcRBcPzcPEcPQcPEcPQcPEcPzcPFcPFcPFcPFcPFcPzcPGcPRcPGcPRcPGcPzcQGcPTcPTcPTcQHcPK cOkcPgcPkcPdcPicOZcPbcPlcQVcQKcRncRncROcQtcRDcRlcRlcRncRPcPkcPdcPlcPfcPicPhcPncOicOAcOBcOCcODcPocPpcPqcOHcPvcPscPtcPucOxcOycOzcOAcQOcRJcRKcRocRpcRQcPrcPvcPscPtcPucOxcOycOzcOAcOQcOTcOUcPgcPkcPdcPicOZcRjcRtcRtcRtcRtcRtcRtcRtcRtcRtcRjcPjcPacPkcPdcPlcOUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQvcQZcRwcQvcRRcRacQvcQZcRacQvcRScRbcQvcQZcRecQvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgcRTcRhcRhcRhcRhcRhcRhcRhcRTcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacPwcPYcPxcRUcPxcPLcPzcPAcPBcPAcPBcPAcPzcRVcRWcRXcRYcRVcPzcPEcPEcPEcPEcPEcPzcPFcPFcPFcPFcPFcPzcPGcPGcPGcPGcPGcPzcRZcSacSacSacSbcPK cOqcPicPncPmcPlcPccQVcQVcSccQrcSdcSdcSecRmcROcRlcRlcRncRPcRPcSfcPbcPecPlcPdcOZcOrcPpcPqcPrcPvcPscPtcPucOMcOycOzcOAcOBcOCcODcPocPpcSgcShcSicSjcQOcSicOxcOycOzcOAcOBcOCcODcPocPpcOGcOTcOUcPicPncPmcPlcPccQXcRtcRtcRtcRtcRtcRtcRtcRtcRtcQqcPgcPhcPncPmcPbcOUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQvcRvcRacQvcRvcRbcQvcRvcRbcQvcRvcSkcQvcRvcSlcQvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgcQwcSmcRhcRhcSncRhcRhcSocQwcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacSpcSqcSqcSqcSqcSqcQgcSqcSqcSqcSqcSqcQgcSqcSqcSqcSqcSqcQgcSrcSrcSrcSrcSrcQgcSrcSrcSrcSrcSrcQgcSrcSrcSrcSrcSrcQgcSrcSrcSrcSrcSrcSs -cOncPlcOZcPjcPbcPfcSfcRncRkcStcRncRkcStcQscSecQscSecSdcREcRDcRucPkcPacPbcPmcPccOucOycOzcOAcOBcOCcODcPocOFcPqcPrcPvcPscPtcPucOxcOycOCcOAcOBcOCcODcPrcPpcPqcPrcPvcPscPtcPucOxcOycOOcOTcOUcPlcOZcPjcPbcPfcQUcRtcRtcRtcRtcRtcRtcRtcRtcRtcQTcPicPdcOZcPjcPkcOUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgcQwcSucRhcRhcRhcRhcRhcSvcQwcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacPwcSwcSxcSycSwcSxcPzcSzcSzcSzcSzcSzcPzcSAcSAcSAcSAcSAcPzcSBcSBcSCcSDcSDcPzcSEcSEcSEcSEcSEcPzcSFcSGcSGcSGcSHcPzcSIcSJcSJcSJcSKcPK +cOncPlcOZcPjcPbcPfcSfcRncRkcStcRncRkcStcQscSecQscSecSdcREcRDcRucPkcPacPbcPmcPccOucOycOzcOAcOBcOCcODcPocOFcPqcPrcPvcPscPtcPucOxcOycOCcOAcOBcOCcODcPrcPpcPqcPrcPvcPscPtcPucOxcOycOOcOTcOUcPlcOZcPjcPbcPfcQUcRtcRtcRtcRtcRtcRtcRtcRtcRtcQTcPicPdcOZcPjcPkcOUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvcQvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgcQwcRfcRhcRhcRhcRhcRhcSucQwcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacPwcSwcSxcSycSwcSxcPzcSzcSzcSzcSzcSzcPzcSAcSAcSAcSAcSAcPzcSBcSBcSCcSDcSDcPzcSEcSEcSEcSEcSEcPzcSFcSGcSGcSGcSHcPzcSIcSJcSJcSJcSKcPK cOvcPbcPccPgcPkcPecRucSdcREcRFcSdcREcRFcRlcQKcRlcQKcStcQtcROcRMcPncPhcPkcPjcPfcOlcOCcODcPocPpcPqcPrcPvcOJcPtcPucOxcOycOzcOAcOBcOCcOzcPqcPrcPvcPscPocPscPtcPucOxcOycOzcOAcOBcOCcOScOTcOUcPbcPccPgcPkcPecQqcRtcRtcRtcRtcRtcRtcRtcRtcRtcQWcPlcPmcPccPgcPncOUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgcQwcRhcRhcRhcQwcQwcRhcRhcQwcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacPwcSxcSycSwcSxcSycPzcSzcSLcSzcSzcSzcPzcSAcSMcSNcSOcSAcPzcSPcSPcSQcSRcSRcPzcSEcSScSEcSTcSEcPzcSUcSVcSVcSVcSWcPzcSXcSYcSYcSYcSZcPK cOscPkcPfcPicPncPacRMcStcQtcRDcStcQtcRDcRncQrcRncQrcRFcRmcSecTacOZcPdcPncPgcPecOtcPrcPvcPscPtcPucOxcOycOOcOAcOBcOCcODcPocPpcPqcPrcShcQNcTbcSgcTccQQcOzcOAcOBcOCcODcPocPpcPqcPrcOIcOTcOUcPkcPfcPicPncPacQTcRtcRtcRtcRtcRtcRtcRtcRtcRtcRCcPbcPjcPfcPicOZcOUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgcQwcRhcRhcRhcQwcTdcRhcRhcQwcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacPwcSycSwcSxcSycSwcPzcSzcSzcSzcTecSzcPzcSAcTfcTfcTfcSAcPzcSPcTgcTgcTgcSRcPzcSEcSEcSEcSEcSEcPzcSUcSVcSVcSVcSWcPzcSXcSYcSYcSYcSZcPK cOicPncPecPlcOZcPhcTacRFcRmcROcRFcRmcROcSdcRkcSdcRkcRDcQscQKcQLcPccPmcOZcPicPacOwcPscPtcPucOxcOycOzcOAcOQcOCcODcPocPpcPqcPrcPvcPscQQcThcTicTjcTkcTlcOBcOCcODcPocPpcPqcPrcPvcPscOKcOTcOUcPncPecPlcOZcPhcQWcRtcRtcRtcRtcRtcRtcRtcRtcRtcQVcPkcPgcPecPlcPccOUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTmcTmcTmcTmcTmcTncTncTocTpcTpcTqcTncTncTncTncTncTncTncTncTncTrcTncTncTnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgcQwcRhcRhcRhcQwcTscRycTtcQwcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacPwcSwcSxcSycSwcSxcPzcSzcSzcSzcSzcSzcPzcSAcSAcSAcSAcSAcPzcSPcSQcSQcSQcSRcPzcSEcSEcSEcSEcSEcPzcSUcSVcSVcSVcSWcPzcSXcSYcSYcSYcSZcPK cOrcOZcPacPbcPccPdcQLcRDcQscSecRDcQscSecStcREcStcREcROcRlcQrcQMcPfcPjcPccPlcPhcOjcODcPocPpcPqcPrcPvcPscOKcPucOxcOycOzcOAcOBcOCcODcTucTvcTwcTxcTycTzcPtcPucOxcOycOzcOAcOBcOCcODcOEcOTcOUcOZcPacPbcPccPdcRCcRtcRtcRtcRtcRtcRtcRtcRtcRtcSfcPncPicPacPbcPfcOUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTAcTBcTCcTBcTmcTncTDcTEcTFcTGcTGcTHcTIcTJcTKcTLcTMcTNcTOcTNcTNcTNcTPcTnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgcQwcTQcTRcTRcQwcTscRycTtcQwcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacPwcSxcSycSwcSxcSycPzcSzcSzcSzcTScSzcPzcSAcTTcTUcTVcSAcPzcTWcTXcTXcTXcTYcPzcSEcTZcSEcSEcSEcPzcUacUbcUbcUbcUccPzcSXcSYcSYcSYcSZcPK cOucPccPhcPkcPfcPmcQMcROcRlcQKcROcRlcQKcRFcQtcRFcQtcSecRncRkcQIcPecPgcPfcPbcPdcOmcPvcPscPtcPucOxcOycOzcOPcOBcOCcODcPocPpcPqcPrcPvcSicUdcUecUfcTvcUgcOAcOBcOCcODcPocPpcPqcPrcPvcOJcOTcOUcPccPhcPkcPfcPmcQVcRtcRtcRtcRtcRtcRtcRtcRtcRtcRucOZcPlcPhcPkcPecOUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTmcTmcTmcTBcTBcTBcTmcTncTDcTEcTEcTEcTEcTEcUhcUicUicUicUjcTNcTNcTNcUkcTNcTNcTnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgcQwcUlcTRcUmcQwcUncRycUocQwcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacPwcSycSwcSxcSycSwcPzcSzcUpcSzcSzcSzcPzcSAcUqcUrcUscSAcPzcUtcUucUucUucUvcPzcSEcSEcSEcUwcSEcPzcUxcUycUycUycUzcPzcUAcSYcSYcSYcUBcPK cOlcPfcPdcPncPecPjcQIcSecRncQrcSecRncQrcRDcRmcRDcRmcQKcSdcREcRjcPacPicPecPkcPmcOpcOzcOAcOBcOCcODcPocPpcOGcPrcPvcPscPtcPucOxcOycOzcQRcTucUCcQNcTbcSgcPqcPrcPvcPscPtcPucOxcOycOzcOPcOTcOUcPfcPdcPncPecPjcSfcRtcRtcRtcRtcRtcRtcRtcRtcRtcRMcPccPbcPdcPncPacOUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUDcUEcUFcTBcTBcTBcTmcTncUGcTEcUHcUIcUJcUKcULcUicUicUicUicTNcTNcUMcTNcUNcTOcTnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgcQwcUOcUPcTRcQwcTscRycTtcQwcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacPwcSwcSxcSycSwcSxcPzcSzcSzcSzcSzcSLcPzcSAcUqcUrcUscSAcPzcUQcSQcURcSQcUScPzcSEcSEcSEcSEcSEcPzcUTcSVcSVcSVcUUcPzcUAcSYcSYcSYcUBcPK -cOtcPecPmcOZcPacPgcRjcQKcSdcRkcQKcSdcRkcROcQscROcQscQrcStcQtcQXcPhcPlcPacPncPjcOocPqcPrcPvcPscPtcPucOxcONcOzcOAcOBcOCcODcPocPpcPqcPrcPvcPscPtcPucOxcOycOzcOAcOBcOCcODcPocPpcPqcOHcOTcOUcPecPmcOZcPacPgcRucRtcRtcRtcRtcRtcRtcRtcRtcRtcTacPfcPkcPmcOZcPhcOUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUVcUWcUEcTBcTBcTBcTmcTncUXcUicUjcUjcUjcUjcUjcUicUicUicUicTNcTNcTNcUYcTNcTNcTnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgcQwcUZcVacTRcQwcTscVbcTtcQwcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacPwcSxcSycSwcSxcSycPzcVccSzcSzcSzcSzcPzcSAcUqcUrcUscSAcPzcUQcVdcVdcVdcUScPzcVecVecVecVecVecPzcUTcSVcSVcSVcUUcPzcUAcSYcSYcSYcUBcPK +cOtcPecPmcOZcPacPgcRjcQKcSdcRkcQKcSdcRkcROcQscROcQscQrcStcQtcQXcPhcPlcPacPncPjcOocPqcPrcPvcPscPtcPucOxcONcOzcOAcOBcOCcODcPocPpcPqcPrcPvcPscPtcPucOxcOycOzcOAcOBcOCcODcPocPpcPqcOHcOTcOUcPecPmcOZcPacPgcRucRtcRtcRtcRtcRtcRtcRtcRtcRtcTacPfcPkcPmcOZcPhcOUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUVcUWcUEcTBcTBcTBcTmcTncUXcUicUjcUjcUjcUjcUjcUicUicUicUicTNcTNcTNcUYcTNcTNcTnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgcQwcUZcSvcTRcQwcTscVacTtcQwcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacPwcSxcSycSwcSxcSycPzcVccSzcSzcSzcSzcPzcSAcUqcUrcUscSAcPzcUQcVdcVdcVdcUScPzcVecVecVecVecVecPzcUTcSVcSVcSVcUUcPzcUAcSYcSYcSYcUBcPK cOwcPacPjcPccPhcPicQXcQrcStcREcQrcStcREcSecRlcSecRlcRkcRFcRmcQUcPdcPbcPhcOZcPgcOkcOBcOCcODcPocPpcPqcPrcOIcPscPtcPucOxcOycOzcOAcOBcOCcODcPocPpcPqcPrcPvcPscPtcPucOxcOycOzcOAcOBcORcOTcOUcPacPjcPccPhcPicRMcRtcRtcRtcRtcRtcRtcRtcRtcRtcQLcPecPncPjcPccPdcOUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTmcTmcTmcTmcTmcTmcTmcTncVfcUicUicUicUicUicUicUicUicUicUicVgcTNcTNcTNcTNcTNcTnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgcQwcQwcQwcQwcQwcQwcQwcQwcQwcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacPwcSycSwcSxcSycSwcPzcSzcTScSzcUpcSzcPzcSAcVhcVicVjcSAcPzcUQcUQcSQcUScUScPzcVkcVkcVkcVkcVkcPzcUTcSVcSVcSVcUUcPzcUAcSYcSYcSYcUBcPK cOjcPhcPgcPfcPdcPlcQUcRkcRFcQtcRkcRFcQtcQKcRncQKcRncREcRDcQscQqcPmcPkcPdcPccPicOqcPucOxcOycOzcOAcOBcOCcOScPocPpcPqcPrcPvcPscPtcPucOxcOycOzcOAcOBcOCcODcPocPpcPqcPrcPvcPscPtcPucOMcOTcOUcPhcPgcPfcPdcPlcTacRtcRtcRtcRtcRtcRtcRtcRtcRtcQMcPacOZcPgcPfcPmcOUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTncVfcUicUicUicUicUicVlcUicUicVlcUicVmcVncVncVncVocVncTnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgcQwcVpcVpcVpcVpcVpcVpcVpcQwcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacPwcSwcSxcSycSwcSxcPzcSzcSzcSzcSzcVccPzcSAcSAcSAcSAcSAcPzcVqcVqcVrcVscVscPzcVtcVtcVtcVtcVtcPzcVucVvcVvcVvcVwcPzcVxcVycVycVycVzcPK cOmcPdcPicPecPmcPbcQqcREcRDcRmcREcRDcRmcQrcSdcQrcSdcQtcROcRlcQTcPjcPncPmcPfcPlcOncPscPtcPucOxcOycOzcOAcOQcOCcODcPocPpcPqcPrcPvcPscPtcPucOxcOycOzcOAcOBcOCcODcPocPpcPqcPrcPvcPscOKcOTcOUcPdcPicPecPmcPbcQLcRtcRtcRtcRtcRtcRtcRtcRtcRtcQIcPhcPccPicPecPjcOUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTncVAcUicUicUicUicUjcVBcUjcUjcVBcUjcVCcVDcVDcVDcVDcVDcTnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgcQwcVEcVEcVEcVEcVEcVEcVEcQwcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacVFcVGcVGcVGcVGcVGcVHcVGcVGcVGcVGcVGcVHcVGcVGcVGcVGcVGcVHcVGcVGcVGcVGcVGcVHcVGcVGcVGcVGcVGcVHcVGcVGcVGcVGcVGcVHcVGcVGcVGcVGcVGcVI @@ -12930,41 +13406,41 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfydfydfydfydfydfHdfMdfJdfPdfQdfJdfMdfMdfMdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfRdfMdfMdfMdfMdfMdfMdfMdfMdfMdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfSdfMdfMdfMdfMdfMdfMdfMdfHdfHdfydfydfydfydfydfydfydfydfydfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdfTdfTdfTdfTdfTdfTdfTdfUaaaaaaaaaaaaaaaaaaaaaaaadfydfydfydfydfydfMdfMdfJdfPdfLdfJdfMdfHdfVdfydfWdfXdfXdfYdfydfZdgadgbdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdgcdgddgedgfdggdghdfTdfUaaaaaaaaaaaaaaaaaaaaaaaadfydfzdfAdfBdfydfMdfMdfJdfPdgidfJdfMdfHdfHdfydgjdgjdgjdgjdfydgkdgadgldfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadgmdgndgndgndgndgndgndgndgndgndgndgndgndgndgodgpdgndgndgndgodgqdgrdgsdgfdgfdgfdfTdfUaaaaaaaaaaaaaaaaaaaaaaaadfydfFdfAdfAdfGdfMdfMdfMdfMdfMdfMdfMdfMdfMdfydgjdgtdgudgudfydfydgvdfydfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdgcdgwdgedgfdgfdghdfTdfUaaaaaaaaaaaaaaaaaaaaaaaadfydfydfydfydfydfydfydgxdfydfydfydfMdfMdfMdgydgjdgzdgzdgjdgjdgjdgjdgAdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadgmdgndgndgndgndgndgndgndgndgndgndgndgndgndgBdgpdgndgndgndgBdgqdgrdgsdgfdgfdgfdfTdfUaaaaaaaaaaaaaaaaaaaaaaaadfydgCdgDdgEdfydgFdgGdgGdgGdgHdfydfMdfMdfMdfMdgjdgjdgjdgjdgIdgjdgjdgudfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdgcdgwdgedgfdgfdghdfTdfTdfTdfTdfTdfTaaaaaaaaaaaadfydgJdgKdgLdgMdgGdgGdgGdgGdgNdfydfMdfMdfMdgydgOdgjdgjdgjdgPdgjdgjdgQdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadgmdgndgndgndgndgndgndgndgndgndgndgndgndgndgRdgpdgndgndgndgRdgqdgrdgsdgfdgfdgfdfTdgSdgTdgTdgUdfTaaaaaaaaaaaadfydfydgVdgWdfydfydfydgVdgXdgWdfydfMdfMdfMdfydgYdgZdgZdgZdgZdgZdhadfydfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdgcdgwdgedgfdgfdghdfTdhbdgTdgTdhcdfTaaaaaaaaaaaadfydhddhddhddhddhddhddhddhddhddfydfydhedfydfydhddhddhddhddhddhddhddfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadgmdgndgndgndgndgndgndgndgndgndgndgndgndgndhfdgpdgndgndgndhfdgqdhgdgsdgfdgfdgfdfTdhhdgTdgTdhidfTaaaaaaaaaaaadfydfydfydfydfydfydfydfydfydfydfydhjdhkdhldfydfydfydfydfydfydfydfydfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdhmdfTdfTdfTdfTdgTdgTdfTdfTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfydhndhodhpdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdhqdgTdgTdhrdgTdgTdgTdgTdhsdfTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfydhndhodhpdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdhtdgTdgTdgTdgTdgTdgTdgTdhudfTaaaaaaaaaaaaaaaaaaaaaaaadfydfydfydfydfydfydfydhvdhwdhxdfydfydfydfydfydfydfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdhydgTdgTdgTdgTdgTdgTdgTdhzdfTaaaaaaaaaaaaaaaaaaaaaaaadfydhjdhkdhkdhkdhkdhkdhAdhodhBdhkdhkdhkdhkdhkdhldfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdhCdgTdgTdgTdgTdgTdgTdgTdhDdfTaaaaaaaaaaaaaaaaaaaaaaaadfydhndhodhodhodhodhodhodhodhodhodhodhodhodhodhpdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdfTdhEdhFdhGdfTdfTdfTdhHdhIdhJdhKdfTdfTdfTdfTdhLdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTaaadfydhndhodhMdhNdhNdhNdhNdhNdhNdhNdhNdhNdhOdhodhpdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdhPdhQdhQdhQdhRdfTdfTdhSdhQdhQdhQdhTdfTdfTdhUdgTdgTdfTdhVdhVdhVdhVdhVdhVdhWdhXdhYdfTaaadfydhndhodhpdhZdgXdgXdgXdgXdgXdgXdgXdiadhndhodhpdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdhPdhQdhQdhQdibdfTdfTdhSdhQdhQdhQdicdfTdfTdiddhQdiedifdhQdhQdhQdhQdhQdhQdigdfTdfTdfTdfTdfydhndhodhpdihdiidijdikdildimdindiodihdhndhodhpdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdipdhQdhQdhQdiqdfTdfTdirdhQdhQdhQdisdfTdfTditdhQdgfdfTdiudivdivdivdivdivdiwdfTdixdixdixdfydhAdhodhBdiydizdhodiAdiBdiCdhodhodiydhAdhodhBdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdfTdfTdfTdfTdfTdfTdfTdfTdiDdfTdfTdfTdfTdfTdfTdiEdfTdfTdfTdfTdhQdhQdiediFdiGdiGdiGdiGdiGdiGdiGdiHdiGdiGdiGdiIdhodhodhodiJdiKdhodhodhodhodhodhodiJdhodhodhodiLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdfTdiMdiNdiOdiPdfTdgTdiQdgTdiQdgTdgTdiRdgTdiSdgTdiSdgTdiRdhQdhQdhQdiTdfTdfTdiWdiVdiUdfTdfTdhXdfTdiXdiXdiXdfydhOdhodhMdiYdhodhodhodhodhodhodhodiYdhOdhodhMdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdiZdhQdhQdhQdhQdjadgTdgTdgTdgTdgTdgTdgTdgTdgTdgTdjbdjbdjbdgTdgTdgTdjcdfTdjddjedjedjedjfdfTdhYdfTdfTdfTdfTdfydhndhodhpdiydjgdjhdjidjidjidjjdjkdiydhndhodhpdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdiZdhQdhQdhQdhQdfTdgTdgTdgTdgTdgTdgTdgTdgTdgTdjldjmdjndjodjpdgTdgTdjqdfTdjrdjsdjtdjudjedfTdfTdfTaaaaaaaaadfydhndhodhpdfydfydjvdjwdjxdjydjzdfydfydhndhodhpdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdjAdhQdjBdjCdjDdfTdfTdfTdjEdfTdfTdfTdjFdgTdgTdjldjmdjmdjmdjpdgTdgTdjGdfTdjedjHdjIdjJdjKdfTaaaaaaaaaaaaaaadfydhndhodhpdfydfydgYdgXdgXdgXdhadfydfydhndhodhpdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdfTdfTdfTdfTdfTdfTdjLdiRdhQdhQdjMdfTdjNdgTdgTdgTdigdigdigdgTdgTdgTdjOdfTdjedjPdjQdjRdjSdfTaaaaaaaaaaaaaaadfydhndhodhBdhkdhkdhkdhkdhkdhkdhkdhkdhkdhAdhodhpdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdjTdhQdhQdhQdjUdfTdjVdgTdgTdgTdgTdgTdgTdjWdgTdgTdjXdfTdjedjYdjZdkadjedfTaaaaaaaaaaaaaaadfydhndhodhodhodhodhodhodhodhodhodhodhodhodhodhpdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkbdkcdkdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdkedhQdhQdhQdkfdfTdfTdfTdfTdfTdfTdkgdkgdfTdfTdfTdfTdfTdkhdjedkidkjdkkdfTaaaaaaaaaaaaaaadfydkldhNdhNdhNdhNdhNdhOdhodhMdhNdhNdhNdhNdhNdkmdfyaaaaaaaaaaaaaaaaaaaaaaaaaaadkbdkndkodkpdkdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdfTdkqdkrdksdfTdfTaaaaaaaaaaaadktdkudkvdktaaaaaaaaadfTdfTdfTdfTdfTdfTdfTaaaaaaaaaaaaaaadfydfydfydfydfydfydfydfydkwdfydfydfydfydfydfydfydfyaaaaaaaaaaaaaaaaaaaaaaaadkbdkndkxdkydkzdkpdkdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdfTdfTdfTdfTdfTdfTaaaaaaaaaaaadkAdkBdkCdkAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkDdkEdkFdkGdkHdkIdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkcdkJdkKdkLdkKdkMdkcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkNdkOdkOdkOdkOdkPdkPdkOdkOdkQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkDdkRdkSdkTdkSdkUdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkbdkndkVdkLdkLdkLdkWdkpdkdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkXdkYdkZdladlbdlcdlcdlddledkOdkQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkDdlfdlgdkGdlhdkUdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlidljdlkdkLdkLdkLdlldkLdliaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkXdkYdlmdlcdlcdlcdlcdlcdlcdlndlodfTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkDdlpdlqdlrdlqdlqdkDdkDdkDdkDdkDdkDdkDdkDdkDaaaaaadkbdlsdltdlsdlsdlsdludlsdlvdlsdltdlsdkdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlwdlwdlwaaadlxdlxdlxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkXdkYdlcdlydlydlydlydlydlydkOdlzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkDdkDdlAdlBdlCdlBdkEdkIdlDdlEdlEdlFdlEdlEdlFdkDaaaaaadlidlGdlHdlIdlJdlGdkLdlIdlJdlGdlHdlIdliaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlwdlwdlwaaadlxdlxdlxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlKdkOdkOdkOdkOdkOdkOdkOdkOdlzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlLdkEdlMdlMdlMdlMdkFdkUdlDdlEdkDdlNdlOdlOdlPdkDaaaaaadlidlQdkLdlIdlRdlGdkLdlIdlRdlGdkLdlSdliaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlwdlwdlwaaadlxdlxdlxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlTdlfdlUdlVdkGdlUdlVdkUdlDdlEdkDdlWdlWdlWdlWdkDaaaaaadkcdlGdkLdlIdlRdlGdkLdlIdlRdlGdkLdlIdkcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlXdlYdlZdmadmbdlwdlwdlwaaadlxdlxdlxdlXdlYdlZdmadmbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlTdlfdlUdlVdkGdlUdlVdkUdlBdlEdkDdkGdkGdkGdmcdmddlOdlPdlidlGdkLdlIdmedlGdkLdlIdmedlGdkLdlIdliaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmfdmgdmgdmgdmhdmidmjdmidmidmidmkdmidmldmgdmgdmgdmfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfydfydfydfydfydfMdfMdfJdfPdfLdfJdfMdhCdfVdfydfWdfXdfXdfYdfydfZdgadgbdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfydfzdfAdfBdfydfMdfMdfJdfPdgidfJdfMdfHdfHdfydgjdgjdgjdgjdfydgkdgadgldfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfydfFdfAdfAdfGdfMdfMdfMdfMdfMdfMdfMdfMdfMdfydgjdgtdgudgudfydfydgvdfydfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfydfydfydfydfydfydfydgxdfydfydfydfMdfMdfMdgydgjdgzdgzdgjdgjdgjdgjdgAdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfydgCdgDdgEdfydgFdgGdgGdgGdgHdfydfMdfMdfMdfMdgjdgjdgjdgjdgIdgjdgjdgudfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdfTdfTdfTdfTdfTdfTdfTaaaaaaaaaaaaaaaaaadfydgJdgKdgLdgMdgGdgGdgGdgGdgNdfydfMdfMdfMdgydgOdgjdgjdgjdgPdgjdgjdgQdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdgccVbdfUdjNdjVdjFdfTaaaaaaaaaaaaaaaaaadfydfydgVdgWdfydfydfydgVdgXdgWdfydfMdfMdfMdfydgYdgZdgZdgZdgZdgZdhadfydfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadgmdgndgndgndgndgndgndgndgndgndgndgndgndgndgodgpdgndgndgndgodgqdgrdgsdgfdgfdgfdfTaaaaaaaaaaaaaaaaaadfydhddhddhddhddhddhddhddhddhddfydfydhedfydfydhddhddhddhddhddhddhddfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdgcdgddgedgfdgfdiTdfTaaaaaaaaaaaaaaaaaadfydfydfydfydfydfydfydfydfydfydfydhjdhkdhldfydfydfydfydfydfydfydfydfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadgmdgndgndgndgndgndgndgndgndgndgndgndgndgndgBdgpdgndgndgndgBdgqdgrdgsdgfdgfdjcdfTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfydhndhodhpdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdgcdgddgedgfdgfdjqdfTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfydhndhodhpdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadgmdgndgndgndgndgndgndgndgndgndgndgndgndgndgRdgpdgndgndgndgRdgqdgrdgsdgfdgfdjGdfTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfydfydfydfydfydfydfydhvdhwdhxdfydfydfydfydfydfydfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdgcdgddgedgfdgfdjOdfTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfydhjdhkdhkdhkdhkdhkdhAdhodhBdhkdhkdhkdhkdhkdhldfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadgmdgndgndgndgndgndgndgndgndgndgndgndgndgndhfdgpdgndgndgndhfdgqdhgdgsdgfdgfdjXdfTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfydhndhodhodhodhodhodhodhodhodhodhodhodhodhodhpdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdhmdggdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTdfTaaadfydhndhodhMdhNdhNdhNdhNdhNdhNdhNdhNdhNdhOdhodhpdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdgUdghdgSdfTdhhdhbdhcdfTdgTdgTdfTdhVdhVdhVdhVdhVdhVdhWdhXdhYdfTaaadfydhndhodhpdhZdgXdgXdgXdgXdgXdgXdgXdiadhndhodhpdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdhqdgfdhidfTdhsdgfdhrdfTdgTdgTdifdhQdhQdhQdhQdhQdhQdigdfTdfTdfTdfTdfydhndhodhpdihdiidjhdijdildimdindiodihdhndhodhpdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdgTdgTdgTdfTdgTdgTdgTdfTdgTdgTdfTdiudivdivdivdivdivdiwdfTdixdixdixdfydhAdhodhBdiydizdhodikdiBdiCdhodhodiydhAdhodhBdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdfTdfTdfTdfTdfTdhtdfTdfTdfTdhudfTdfTdgTdgTdiFdiGdiGdiGdiGdiGdiGdiGdiHdiGdiGdiGdiIdhodhodhodiJdhodhodhodhodhodhodhodiJdhodhodhodiLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdhzdhydgTdfTdgTdgTdgTdhDdgTdgTdgTdgTdgTdgTdfTdfTdiUdiVdiUdfTdfTdhXdfTdiXdiXdiXdfydhOdhodhMdiYdhodhodhodhodhodhodhodiYdhOdhodhMdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdhFdgfdgTdhGdgTdgTdgTdgTdgTdhHdjodhEdhJdgTdfTdjddjedjedjedjfdfTdhYdfTdfTdfTdfTdfydhndhodhpdiydjgdjhdjidjidjidjjdjkdiydhndhodhpdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdhLdhKdgTdfTdgTdgTdgTdgTdgTdhJdhPdhTdjodgTdfTdjrdjsdjtdjudjedfTdfTdfTdhjdhkdhldfydhndhodhpdfydfydjvdjwdjxdjydjzdfydfydhndhodhpdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdfTdfTdfTdfTdfTdhUdfTdfTdgTdjodhJdhRdhJdgTdfTdjedjHdjIdjJdjKdfTdiAdhkdhAdhodhoeHydhodhodhpdfydfydgYdgXdgXdgXdhadfydfydhndhodhpdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdgTdgTdgTdfTdgTdgTdgTdgTdjWdgTdfTdjedjPdjQdjRdjSdfTdiKdhodhodhodhpdiYdhndhodhBdhkdhkdhkdhkdhkdhkdhkdhkdhkdhAdhodhpdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdicdgfdibdfTdfTdfTdkgdkgdfTdfTdfTdjedjYdjZdkadjedfTdpFdhodhodhodtBdihdhndhodhodhodhodhodhodhodhodhodhodhodhodhodhpdfyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkbdkcdkdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdipdiddiedfTdiqdktdkudkvdktdiqdfTdkhdtCdkidkjdkkdfTduadhNdhNdhNeHxdiydkldhNdhNdhNdhNdhNdhOdhodhMdhNdhNdhNdhNdhNdkmdfyaaaaaaaaaaaaaaaaaaaaaaaaaaadkbdkndkodkpdkdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfTdfTdfTdfTdfTdiqdkAdkBdkCdkAdiqdfTdfTdfTdfTdfTdfTdfTdfydfydfydfydfydfydfydfydfydfydfydfydfydkwdfydfydfydfydfydfydfydfyaaaaaaaaaaaaaaaaaaaaaaaadkbdkndkxdkydkzdkpdkdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgdkNdkOdkOdkOdkOdkPdkPdkOdkOdirdiqcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkDdkEdkFdkGdkHdkIdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkcdkJdkKdkLdkKdkMdkcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgdkXdkYdkZdladlbdlcdlcdlddledkOdircQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkDdkRdkSdkTdkSdkUdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkbdkndkVdkLdkLdkLdkWdkpdkdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgdkXdkYdlmdlcdlcdlcdlcdlcdlcdlndlodfTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkDdlfdlgdkGdlhdkUdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlidljdlkdkLdkLdkLdlldkLdliaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgdkXdkYdlcdlydlydlydlydlydlydkOdiscQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkDdlpdlqdlrdlBdlPdkDdkDdkDdkDdkDdkDdkDdkDdkDaaaaaadkbdlsdltdlsdlsdlsdludlsdlvdlsdltdlsdkdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlwdlwdlwaaadlxdlxdlxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgdlKdkOdkOdkOdkOdkOdkOdkOdkOdisdiqcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkDdkDdlAdlCdlDdlCdkEdkIdlqdlEdlEdlFdlEdlEdlFdkDaaaaaadlidlGdlHdlIdlJdlGdkLdlIdlJdlGdlHdlIdliaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlwdlwdlwaaadlxdlxdlxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQgcQgcQgcQgcQgcQgcQgcQgcQgcQgcQgcQgcQgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlLdkEdlMdlMdlMdlMdkFdkUdlTdlEdkDdlNdlOdlOdlPdkDaaaaaadlidlQdkLdlIdlRdlGdkLdlIdlRdlGdkLdlSdliaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlwdlwdlwaaadlxdlxdlxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlTdlfdlUdlVdkGdlUdlVdkUdlTdlEdkDdlWdlWdlWdlWdkDaaaaaadkcdlGdkLdlIdlRdlGdkLdlIdlRdlGdkLdlIdkcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlXdlYdlZdmadmbdlwdlwdlwaaadlxdlxdlxdlXdlYdlZdmadmbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlTdlfdlUdlVdkGdlUdlVdkUdlCdlEdkDdkGdkGdkGdmcdmddlOdlPdlidlGdkLdlIdmedlGdkLdlIdmedlGdkLdlIdliaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmfdmgdmgdmgdmhdmidmjdmidmidmidmkdmidmldmgdmgdmgdmfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlTdlfdlUdlVdkGdlUdlVdkUdmmdkSdkDdmndkGdkGdmodmpdmqdmpdmrdkLdkLdkLdkLdkLdkLdkLdkLdkLdkLdlIdliaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmfdmsdmsdmtdmudmvdmwdmxdmydmzdmAdmvdmBdmCdmsdmsdmfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmDdlfdlUdlVdkGdlUdlVdkUdmEdmqdmEdkGdkGdkGdmFdmddlOdlPdlidmGdkLdlIdlJdlGdkLdlIdlJdlGdkLdlSdliaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmfdmsdmsdmHdmIdmJdmKdmJdmLdmJdmKdmJdmMdmHdmsdmsdmfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkDdlpdmNdmNdmNdmOdkGdkUdmmdkSdkDdmndkGdkGdkGdkDaaaaaadlJdlGdkLdlIdlRdlGdkLdlIdlRdlGdkLdlIdlJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmPdmCdmsdmQdmJdmKdmKdmKdmKdmKdmKdmKdmJdmQdmsdmtdmRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -12983,18 +13459,18 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkDdmqdmqdmqdmqdmqdmqdmqdmqdmqdmqdmqdmqdkDdmqdmqdmqdmqdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmfdoMdmJdpcdmJdpddmfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkDdkDdkDdkDdkDdkDdkDdkDdkDdkDdkDdkDdkDdkDdmqdmqdmqdpedkDdkDdkDdkDdkDdkDdkDdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmfdpfdpgdphdpidpjdmfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdowdowdowdowdowdowdowdowdkDdmqdmqdmqdpkdpldpldpldpldpmdpmdpldpldpldpldpndmqdmqdmqdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmPdpodppdppdppdpqdmRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdprdpsdpsdpsdpsdpsdptdowdkDdmqdmqdpkdpudpvdpwdpxdpldpydpzdpldpAdpBdpCdpldpldpndmqdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdpDdpEdpEdpEdpEdpEdpDdowdkDdmqdpkdpldpydpydpydpydpldpFdpFdpldpydpydpydpGdpHdpldpndkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdpDdpEdpEdpEdpEdpEdpDdowdkDdpkdpldpIdpJdpKdpLdpMdpldpydpydpNdpydpydpydpydpydpydpldkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdpDdpEdpEdpEdpEdpEdpOdowdkDdpPdpQdpydpydpRdpRdpRdpldpydpydpldpSdpTdpUdpVdpWdpXdpldkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdpDdpEdpEdpEdpEdpEdpYdowdkDdpZdpQdpydpydpydpydpydqadpydpydpldpldpldpldpldpldpldqbdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdpDdpEdpEdpEdpEdqcdpDdowdkDdqddpldqedqfdqgdqhdpydpldpydpydpldpydqidqjdqkdmqdmqdmqdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdpDdpEdpEdpEdpEdpEdpYdowdkDdmqdpldpldpldpldpldpldpldpydpydqldpydqmdqndqodmqdmqdmqdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdpDdpEdpEdpEdpEdpEdqpdowdkDdpkdpldqqdqrdqsdqqdqtdpldpydpydpldpydqudqvdqwdmqdmqdmqdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdpDdpEdpEdpEdpEdpEdpDdowdkDdpPdpQdqxdqxdqxdqxdqxdqydpydpydpldpldpldpldpldpldpldpndkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdqzdqAdpEdpEdpEdqBdqCdowdkDdpZdpQdqxdqxdqxdqDdqEdpldpydpydpldpydpydpydqFdpydqGdpldkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdprdpsdpsdpsdpsdpsdptdowdkDdmqdmqdpkdpudpvdpwdpxdpleHFdpzdpldpAdpBdpCdpldpldpndmqdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdpDdpEdpEdpEdpEdpEdpDdowdkDdmqdpkdpldpydpydpydpydpleHGeHGdpldpydpydpydpGdpHdpldpndkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdpDdpEdpEdpEdpEdpEdpDdowdkDdpkdpldpIdpJdpKdpLdpMdpleHFdpydpNdpydpydpydpydpydpydpldkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdpDdpEdpEdpEdpEdpEdpOdowdkDdpPdiWdpydpydpRdpRdpRdpldpydpydpldpSdpTdpUdpVdpWdpXdpldkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdpDdpEdpEdpEdpEdpEdpYdowdkDdpZdiWdpydpydpydpydpydqadpydpydpldpldpldpldpldpldpldqbdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdpDdpEdpEdpEdpEdqcdpDdowdkDdqddpldqedqfdqgdqhdpydpldpydpydpldpydqidqjdpQdmqdmqdmqdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdpDdpEdpEdpEdpEdpEdpYdowdkDdmqdpldpldpldpldpldpldpldpydpydqldpydqmdqndqkdmqdmqdmqdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdpDdpEdpEdpEdpEdpEdqpdowdkDdpkdpldqqdqrdqsdqqdqtdpldpydpydpldpydqudqvdqodmqdmqdmqdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdpDdpEdpEdpEdpEdpEdpDdowdkDdpPdiWdqxdqxdqxdqxdqxdqydpydpydpldpldpldpldpldpldpldpndkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdqzdqAdpEdpEdpEdqBdqCdowdkDdpZdiWdqxdqxdqxdqDdqEdpldpydpydpldpydpydpydqwdpydqGdpldkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdqHdqIdqJdqJdqJdqIdqKdowdkDdqddpldqLdqMdqxdqNdqOdpldpydpydqPdpydpydpydqQdpydqGdpldkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdqRdqSdqTdqTdqTdqUdqRdowdkDdmqdqddpldqVdqxdqxdqxdpldpydpydpldqWdpydpydqXdqYdpldqbdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdqRdqSdqTdqTdqTdqUdqRdowdkDdmqdqddpldqVdqxdqxdqxdpldpydpydpldqWdpydpydqFdqYdpldqbdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadowdowdowdowdowdowdowdowdowdkDdmqdmqdqddpldqZdradrbdpldpydpydpldrcdrddpydpldpldqbdmqdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkDdmqdmqdmqdqddpldpldpldpldpldpldpldpldpldpldqbdmqdmqdmqdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkDdkDdkDdkDdkDdkDdkDdkDdkDdkDdkDdkDdkDdkDdkDdkDdkDdkDdkDdkDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -13014,7 +13490,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadrgdredrhdridridridridridrhdrfdrgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadredrhdrjdrkdrldrmdrndrodrpdrqdrfaaaaaaaaaaaaaaaaaadrfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadrrdrsdrtdrtdrtdrtdrtdrudrqdrhdridrhdridrhdridrhdrhdrfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadrrdrvdrtdrwdrxdrydrtdrzdrqdrAdrtdrBdrtdrCdrDdrEdrFdrqdrfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadrrdrvdrtdrwdrxdrydrtdrzdrqdrAdrtdgwdrtdrCdrDdrEdrFdrqdrfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadrrdrGdrtdrHdrIdrJdrtdrKdrqdrtdrtdrtdrtdrtdrtdrtdrLdrraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadrrdrMdrNdrtdrtdrtdrNdrOdrqdrPdrtdrQdrtdrRdrDdrEdrFdrraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadrqdrhdrhdrtdrtdrtdrhdrhdrqdrtdrtdrtdrtdrtdrtdrtdrSdrqdrTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -13027,14 +13503,14 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadrqdsxdsydszdrtdrtdrtdsAdsAdsAdrtdsidrtdrtdrqdsBdrtdrtdsCdrqdsDdstdsEdrtdsFdrqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadrrdrtdrtdrtdrtdrtdsGdrhdrhdrhdrhdrqdrtdrtdrqdrtdrtdsHdsIdrqdsJdrtdrtdrtdsKdrraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadrqdsLdsMdsNdrtdsOdrhdsPdsQdsRdsSdrqdrtdrtdrqdsTdrtdrtdsUdrqdsVdrtdrtdrtdsWdrraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadrrdrtdrtdrtdrtdsXdrhdsYdsQdsQdsQdsZdrtdrtdrqdtadrtdrtdtbdrqdtcdrtdrtdrtdtddrraaaaaaaaaaaadredrhdtedtedtedrhdrfaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadrrdrtdrtdrtdrtdhIdrhdsYdsQdsQdsQdsZdrtdrtdrqdtadrtdrtdtbdrqdtcdrtdrtdrtdtddrraaaaaaaaaaaadredrhdtedtedtedrhdrfaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadrqdtgdthdtidrtdtjdrhdtkdsQdtldtmdrqdrtdrtdrqdtndtodrtdrtdtpdrtdrtdrtdrtdrtdrqaaaaaaaaadredrhdtqdtrdtrdtrdtsdrhdrfaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtfdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdtfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadredrhdrhdrhdrhdrhdrhdrhdrhdrhdrhdrhdtudrtdrtdtvdrhdrhdrhdrhdrhdrhdrhdrhdtwdrhdrqdrfaaadredrhdtqdtrdtrdtrdtrdtrdtsdrhdrfaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtfdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdtfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadredrqdtxdtydtzdtAdtBdtCdtDdtvdrqdtudrtdrtdrtdrtdrtdrtdtvdrhdrhdrhdrhdtEdtudrtdtvdrqdrhdtedrhdtqdtrdtrdtrdtFdtrdtrdtrdtsdrqaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtfdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdtfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadredrqdtxdtydtzdtAeHzeHAdtDdtvdrqdtudrtdrtdrtdrtdrtdrtdtvdrhdrhdrhdrhdtEdtudrtdtvdrqdrhdtedrhdtqdtrdtrdtrdtFdtrdtrdtrdtsdrqaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtfdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdtfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadrrdtGdrtdrtdtHdrtdrtdrtdrtdrtdtIdrtdrtdtJdtJdtJdtJdrtdrtdrtdrtdrtdrtdrtdrtdrtdrtdtKdtrdtrdtrdtrdtrdtrdtLdtMdtNdtrdtrdtrdtOaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtfdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdtfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadrrdtPdtQdrtdrtdrtdrtdrtdrtdrtdtIdrtdrtdtJdtJdtJdtJdrtdrtdrtdrtdrtdrtdrtdrtdrtdrtdtKdtrdtrdtrdtrdtrdtRdtSdtLdtLdtRdtrdtrdtOaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtfdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdtfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadrrdtTdrtdrtdtUdrtdrtdrtdrtdrtdtIdrtdrtdtJdtJdtJdtJdrtdrtdrtdrtdrtdrtdrtdrtdrtdsGdrqdrhdtedrhdtVdtrdtrdtRdtRdtRdtrdtrdtWdrqaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtfdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdtfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsldrqdtXdtYdtZduadubducduddsGdrqdsjdrtdrtdrtdrtdrtdrtdsGdrhdrhdsjduedsGdrhdrhdrhdrqdrTaaadsldrhdtVdtrdtrdtrdtrdtrdtWdrhdrTaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtfdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdtfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsldrqdtXdtYdtZeHBdubducduddsGdrqdsjdrtdrtdrtdrtdrtdrtdsGdrhdrhdsjduedsGdrhdrhdrhdrqdrTaaadsldrhdtVdtrdtrdtrdtrdtrdtWdrhdrTaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtfdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdtfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsldrhdrhdrhdrhdrhdrhdrhdrhdrhdrhdrhdsjdrtdrtdsGdrhdrhdrhdrhdrhdufdrhdrhdrhdrhdrqaaaaaaaaadsldrhdtVdtrdtrdtrdtWdrhdrTaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtfdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdtfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadslaaaaaaaaaaaaaaaaaaaaaaaaaaadrqdrhdugdugdrqaaadrqdsQduhdsQdsQdsQduhdsQdrqdrqaaaaaaaaaaaadsldrhdtedtedtedrhdrTaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtfdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdtfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadredrhdrhdrhdrhdrhdrhdrhdrhdrhdtudrtdrtdrqaaadrqduidsQdsQdujdsQdsQdukdrqdrqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -13057,7 +13533,7 @@ aaaaaaaaaaaaduwdvkdvldvmdvmdvxdvmdvmdvndvodvidvidvidvidvidvydvzdvydvidvidvidvidv aaaaaaaaaaaaduwdvkdvldvmdvmdvmdvmdvmdvndvodvidvidvidvidvidvBdvCdvBdvidvidvidvidvjdvpdvndvqdvqdvqdvqdvqdvldvrduwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtfdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdtfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadrrdvDdrtdrtdrtdvEdrraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaduwdvkdvldvmdvtdvmdvtdvmdvndvodvidvidvidvidvidvFdvGdvHdvidvidvidvidvjdvpdvndvqdvudvqdvudvqdvldvrduwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtfdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdtfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadrrdvIdrtdrtdrtdvJdrraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaduwduwduwdvKdvKdvKdvKdvKduwdvhdvidvidvidvidvidvidvLdvidvidvidvidvidvjdvhduwdvKdvKdvKdvKdvKduwaaaduwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtfdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdttdtfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsldrqdvMdvNdvOdvPdvQdrqdrTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaduwdvRdvRdvRdvRdvRduwdvSdvTdvTdvTdvTdvedvUdvVdvUdvbdvcdvcdvcdvddveduwdvWdvWdvWdvWdvWduwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsldrhdridridridrhdrTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaduwdvRdvRdvRdvRdvRduwdvSdvTdvTdvTdvTdvedvUdksdvUdvbdvcdvcdvcdvddveduwdvWdvWdvWdvWdvWduwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfdtfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsldrhdridridridrhdrTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaduwduwduwduwduwduwduwdvXdvYdvYdvYdvYdvYdvZdwadvXdvYdvYdvYdvYdwbdvXduwduwduwduwduwduwduwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadslaaaaaaaaadrTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaduwdvXdvXdwcdvXdwcdvXdvXdwddwedvXdwcdvXdwcdwfdvXduwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaduxdvXdvXdvXdwgdwgdwgdvXdvXdvXdwgdwgdwgdwgdwgdvXdwhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -13187,7 +13663,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaaidyrdyudytdyudyudzgdzhdzidzjdzkdzldzmdzndzodzfdyHdzpdzqdysdzrdysdzsdztdyHdzudzvdzwdysaaiaaicqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaaidyrdyudytdyudyVdzxdzydzzdzAdzAdzAdzBdzCdzDdzEdzFdzGdzHdzHdzHdysdzIdzJdyHdzKdzLdzMdzNcAGcAGdzOdzPdzQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOcqOcqOcqOcqOcqOcqOcqOcqOcnZcqOcqOcqOcqOcqOcqOcqOcqOcqOcqOcqOaaidyrdyudytdyudyVdzRdzSdzTdzUdzUdzUdysdzVdzWdzXdyHdzYdzZdAadzHdysdysdAbdAcdysdysdysdysaaiaaicqOcqOcqOcqOcqOcqOcqOcqOcqOcqOcqOcqOcqOcqOcqOcqOcqOcnZcqOcqOcqOcqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcqOaaidyrdytdAddytdAedzRdyOdzHdzHdzHdzHdzHdAfdAgdAhdAgdAidAjdAkdAldzHdzHdAmdAndAodytdAddytdyraaicqOcqOcqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcqOaaidyrdytditdytdAedzRdyOdzHdzHdzHdzHdzHdAfdAgdAhdAgdAidAjdAkdAldzHdzHdAmdAndAodytditdytdyraaicqOcqOcqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaabdyodyodyodyodyodyodyodyodyodyodyodyodyodyodyodyoaaaaaacqOaaidyrdyudytdyudyVdApdAqdzHdArdAsdArdAtdAudAvdAwdArdArdAxdAydArdArdzHdAmdAndzadyudytdyudyraaicqOcqOaaaaabdyodyodyodyodyodyodyodyodyodyodyodyodyodyodyodyoaaacqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaaaaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaaacqOaaidyrdyudytdyudyVdAzdAAdzHdArdAydAydAydABdAydACdAydAydABdAydAydArdzHdAmdAndzadADdAEdAFdyraaiaaicqOaabaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaabcqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaaadyodyodyodyodyodyodyodyodyodyodyodyodyodyodyodyoaacaaacqOaaidyrdyudytdyudyVdAGdAHdzHdArdAIdAJdAydABdAydAKdAydAydABdALdAMdArdzHdAmdAndzadANdAOdAPdAQdyraaicqOaaaaacdyodyodyodyodyodyodyodyodyodyodyodyodyodyodyodyoaaacqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -13197,8 +13673,8 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaaadyodyodyodyodyodyodyodyodyodyodyodyodyodyodyodyoaacaaacqOaaidyrdyudytdyudyVdASdzadzHdArdAydAydAydABdAydAKdAydAydABdAydAydArdzHdyVdASdzadBFdBGdBHdBIdyraaicqOaaaaacdyodyodyodyodyodyodyodyodyodyodyodyodyodyodyodyoaaacqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaaaaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaaacqOaaidyrdyudytdyudyVdzRdzadzHdArdBJdBKdBLdBMdAydACdAydAydABdBNdBOdArdzHdyVdASdzadBPdBQdBRdyraaiaaicqOaabaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaabcqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaabdyodyodyodyodyodyodyodyodyodyodyodyodyodyodyodyoaaaaaacqOaaidyrdyudytdyudyVdzRdzadzHdArdArdArdBSdArdArdBTdArdArdBUdArdArdArdzHdyVdASdzadyudytdyudyraaicqOcqOaaaaabdyodyodyodyodyodyodyodyodyodyodyodyodyodyodyodyoaaacqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOcqOaaidyrdytdAddytdAedASdyOdzHdzHdzHdzHdzHdzHdzHdBVdzHdzHdzHdzHdzHdzHdzHdAedASdyOdytdAddytdyraaicqOcqOcqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOcqOcqOcqOcqOcqOcqOcqOcqOcqOcqOcqOcnZcqOcqOcqOcqOcqOcqOcqOcqOaaidyrdyudytdyudyVdBWdBXdBYdzldzldBZdCadCbdCcdCddCedCfdCgdBZdzldzldChdCidASdzadyudytdyudyraaicqOcqOcqOcqOcqOcqOcqOcnZcqOcqOcqOcqOcqOcqOcqOcqOcqOcqOcnZcqOcqOcqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOcqOaaidyrdytditdytdAedASdyOdzHdzHdzHdzHdzHdzHdzHdBVdzHdzHdzHdzHdzHdzHdzHdAedASdyOdytditdytdyraaicqOcqOcqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOcqOcqOcqOcqOcqOcqOcqOcqOcqOcqOcqOcnZcqOcqOcqOcqOcqOcqOcqOcqOaaidyrdyudytdyudyVdBWdBXdBYdzldzldBZdiDdCbdCcdCddCedCfdiEdBZdzldzldChdCidASdzadyudytdyudyraaicqOcqOcqOcqOcqOcqOcqOcnZcqOcqOcqOcqOcqOcqOcqOcqOcqOcqOcnZcqOcqOcqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaaidyrdyudytdyudyVdCjdCkdCkdCkdCkdCldCmdCndCodCpdCqdCrdCsdCtdCkdBrdCkdCkdCudzadyudytdCvdyraaicqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaaidyrdCwdytdyudyudzUdzUdCxdzUdzUdBZdCydCzdCAdCBdCCdCDdCEdBZdzUdzUdzUdzUdzUdyudyudytdyudyraaicqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqOaaidyrdyudytdyudyudyudyudytdyudCFdBZdBZdBZdCGdCHdBZdBZdBZdBZdCFdyudyudyudyudyudyudytdyudyraaicqOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -13255,9 +13731,9 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadDKdDKdDKdDKdDKdDKdDKdDKdDKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadDLdDLdDLdDLdDLaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadDKdDKdDKdDKdDKdDKdDKdDKdDKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabdDLdDLeooeovesbdDLdDLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadDKdDKdDKdDKdDKdDKdDKdDKdDKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabdDLdDLdDPdDOdDOdDOdDRdDLdDLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadDKdDKdDKdDKdDKdDKdDKdDKdDKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjIaQDdDLdDOdDSdDMdDOdDNdDMdDOdDLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadDKdDKdDKdDKdDKdDKdDKdDKdDKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabdDYaacdDVdDOdDUdDNdDTdDOdDOdDQdDLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadDKdDKdDKdDKdDKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjIaQDdDLdDQdDZdDOdRLdDOeojdDXdDLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadDKdDKdDKdDKdDKdDKdDKdDKdDKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkQdlzdDLdDOdDSdDMdDOdDNdDMdDOdDLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadDKdDKdDKdDKdDKdDKdDKdDKdDKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabdDVdDOdDVdDOdDUdDNdDTdDOdDOdDQdDLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadDKdDKdDKdDKdDKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkQdlzdDLdDQdDZdDOdRLdDOeojdDXdDLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadDKdDKdDKdDKdDKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabdDLdDLdDOdDOdDMdDOdEadDLdDLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadDKdDKdDKdDKdDKdDKdDKdDKdDKdDKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabdDLdDLezkdDOezfdDLdDLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadDKdDKdDKdDKdDKdDKdDKdDKdDKdDKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadDLdDLdDWdDOesnaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -13925,7 +14401,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeqJeqJerDerdereercerTercereercergergerDercercercercereerceqJaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabeqgeqjeqjerEeqjeqjerUeqWeqWerierVerWerierWerXerlaacerYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabeqJeqJercereercerZesaeHlescergesdergergeseesfesgerDerdereeqJaaiaabaaaaaaaaaaaaaaaeqEaaaaaaaabaabaabeqgeqgeqgeqneqgeqjeqTeshesiesjeskesleqUeqUeqWerleryaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabeqJeqJerDercerZesmeHkesoergergergergergespespesqesgercerdeqJaaiaabaabaaaaaieqgeqgeqgeqgeqgeqgeqgeqgeqgeqgeqgesreqgeqgeqgessessestessessesseqNeqNeqNdyqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeqJeqJeqJerDerDesuesverdergergergergergergergergeswesxerDesyeqJaaiaaiaabaabaaieqgeszeszeszesAesBesCesDeqgeszeszesEeszeszeqgaaiaabaacaacaaaaaiesFaacaaqdyqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeqJeqJeqJerDerDesuesverdergergergergergergergergeswesxerDesyeqJeqJeqJaabaabaaieqgeszeszeszesAesBesCesDeqgeszeszesEeszeszeqgaaiaabaacaacaaaaaiesFaacaaqdyqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeqJeqJeqJeqJeqJerDerDesuesmerdergesGesGesGesGesGergergesHesxergerDeqJeqJeqJeqJeqJaaaeqgesIesJesJesJesJesJesJesKesJesJesLeszesMeqgaabaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeqJeqJerDesNesOerDerDesPesQergesRaaaaaaaaaaaaaaaesGergesHerAergerDercerDergeqJeqJaabeqgesSeszeszeszeszeszeszeqgesTeszesEeszeszeqgaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeqJeqJesUercesHesgerDerderDergergesGaaaaaaaaaaaaaaaesGergesVergerDesWesXesYercerDeqJeqJeqgeqhesZeqgetaetaetaetaeqgeszeszetbeszeszeqgeqEaaaaaaaaaaaaaaaaaaaaaaaaaacaacaaiaaqaacaaqaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -13978,7 +14454,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaceyHeyVeyHeyWeyXeyYeyYexNeyUexNeyUexNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaacaaceyHeyZezaeyWeyYezbeyYexNeyUexNeyUexNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabexoaacetNeyHezceyHezdeyYezeeHpexNezgexNeyUexNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaacetNezheyYeziezjeyYeHoezleyYexNeyUexNeyUexNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaacetNdEjezheziezjeyYeHoezleyYexNeyUexNeyUexNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaacdEjdEjeyHezmeyHeyYeyYezaeyYexNeyUexNezgexNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaaiaaiaaaeyHeyHezmeyHeyHeyHeyHeyHexNeyUexNezgexNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadyqaaaaaaaaaaaaaaaeznaaaaaaaaaaaaaaadyqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -14001,8 +14477,8 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaaaaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaabaabaacaacaacaacaabaabaabaabaabaabaaaaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabezAezAezAezBezAezAezAaacaacaacaabaaaaaaaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaabaabezBezBezBezBaabaabaabaabaabaabaaaaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabezAezAezAezBezAezAezAezBezBezBaabaaaaaaaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaezAezAezBezBezCezDezCezBezBaabaabaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaezAezEezCezCezCezCezCezCezAaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaezAezCezCezFezGezHezCezIezAaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -14028,23 +14504,23 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaezMaaaaaaezMezMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadKgezMezMaaaezMezMdKgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadKgdKgdKgezMezMezMdKgdKgdKgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadKgdKgdKgezNezMezNdKgdKgdKgdKgezOezPezQezPezRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadKgdKgezOezPezSezPezTdKgdKgdKgezUezVezWezXezUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadKgdKgdKgezUezWezWezWezUdKgdKgezOezUezYezWezXezZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadKgdKgdKgezUeAaezWeAaezUezPezPezPezUeAbezWeAcezZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadKgdKgeAdezPezSezPeAeezWezWezWezSezWeAfeAgezUdKgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadKgdKgdKgdKgezUezWezWezWezWezWeAhezUezPezPezPezPezTdKgdKgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadKgdKgdKgdKgezUezWezWezWezWezWezWezSezWeAjeAkezPezPezPezTdKgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadKgdKgdKgdKgeAdezPezPezPezPezPezPezUeAbezWezWeAleAmeAnezUdKgdKgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadKgdKgdKgdKgdKgdKgdKgdKgdKgeAdezUeAoezWezWezWeApeAqezUdKgdKgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadKgdKgdKgdKgdKgdKgdKgdKgdKgezUeArezWeAseAteAmeAnezUdKgdKgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadKgdKgdKgdKgeAdezPezPezPezPezPezPeAudKgdKgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadKgdKgdKgdKgdKgdKgdKgdKgdKgdKgdKgdKgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadKgdKgdKgdKgdKgdKgdKgdKgdKgdKgdKgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadKgdKgdKgdKgdKgdKgdKgdKgdKgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadKgdKgaaadKgdKgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsXezMezMaaaezMezMdsXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsXdsXdsXezMezMezMdsXdsXdsXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsXdsXdsXezNezMezNdsXdsXdsXdsXezOezPezQezPezRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsXdsXezOezPezSezPezTdsXdsXdsXezUezVezWezXezUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsXdsXdsXezUezWezWezWezUdsXdsXezOezUezYezWezXezZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsXdsXdsXezUeAaezWeAaezUezPezPezPezUeAbezWeAcezZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsXdsXeAdezPezSezPeAeezWezWezWezSezWeAfeAgezUdsXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsXdsXdsXdsXezUezWezWezWezWezWeAhezUezPezPezPezPezTdsXdsXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsXdsXdsXdsXezUezWezWezWezWezWezWezSezWeAjeAkezPezPezPezTdsXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsXdsXdsXdsXeAdezPezPezPezPezPezPezUeAbezWezWeAleAmeAnezUdsXdsXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsXdsXdsXdsXdsXdsXdsXdsXdsXeAdezUeAoezWezWezWeApeAqezUdsXdsXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsXdsXdsXdsXdsXdsXdsXdsXdsXezUeArezWeAseAteAmeAnezUdsXdsXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsXdsXdsXdsXeAdezPezPezPezPezPezPeAudsXdsXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsXdsXdsXdsXdsXdsXdsXdsXdsXdsXdsXdsXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsXdsXdsXdsXdsXdsXdsXdsXdsXdsXdsXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsXdsXdsXdsXdsXdsXdsXdsXdsXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsXdsXaaadsXdsXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -14235,41 +14711,41 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaieAReASeARaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaieATeAUeAVaaieAWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaieAUeAUeAXaaiavfeAYeAZeBaaaiaaiaaieAYeAZeAZeAZeBbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeBceAZeAZeBaaaiaaiaaiaaieAReBdeARaaieBeeBfeBgeBheBiaaieBjeBkeBkeBkeBkeBlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeBleBmeBneBoeBpeBqeBreBseBteBueBveBweBxeByeBzeBgeBAaaieBBeBkeBkeBkeBkeBlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeBleBCeBDeBEeBFeBGeBGeBHeBIeBJeBKeBLeBMeBNeBOeBPeBQeBReBSeBkeBkeBkeBkeBlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeBleBTeBUeBVeBWeBXeBYeBZeCaeCbeCceCdeCeeCfeCgeBgeChaaieCieBkeBkeBkeBkeCjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeCkeCleCleCmaaiaaiaaiaaieCneCoeCpaaieCqeCreCseCteCuaaieBkeCveCweCxeBkaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaieCneCoeCyaaiaaieAYeAZeBaaaiaaiaaieAYeAZeBaaaiaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeBceAZeAZeAZeAZeBaaaiaaiaaieCneCzeCAaaieCBeCCeCCeCCeCCeCDeCCeCCeCCeCEeCFaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeBleCGeCGeCGeCGeCHeCIeCJaaieCKeCLeCMaaieCCeCNeCNeCOeCOeCCeCPeCQeCReCSeCTelGeCVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeBleCGeCGeCGeCGeCGeCGeCWaaieCneCoeCXaaieCYeCNeCNeCOeCOeCCeCZeDaeDbeDceCCeBlaaaeDdeDdeDdeDdeDdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeBleCGeCHeDeeCHeDfeDgeDgeDheDieDjeDkeDleDmeDneDneDneDneDoeCPeDpeDbeDqeDreDseDteDueDveDweDxeDdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeBleCGeDyeDeeCHeDzeDAeDBeDCeDDeDEeDFeDGeDHeCCeDIeCUeDKeCCeCCeCCeDLeCCeDMaEFeDNeDOeDPeDQeDxeDRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeBleCGeCGeCGeCGeCGeCGeDSaaieDTeDUeDVeDWeDXeDYeDYeDYeDYeDZeCQeCPeEaeDJeEceEdeEeeEfeEgeEheDxeDdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeBleCGeCGeCGeCGeCGeEieEjcAGeBteEkeElaaieEmeEneEoeEpeEpeCCeEqeDKeEreDreEseBlaaaeDdeDdeDdeDdeDdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeCkeCleCleCleCleCmaaiaaiaaieEteEueEvaaieEweEneEoeEpeEpeCCeDpeCPeAieDreEyeEzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaieEAeCoeEBaaieCCeECeCCeCCeCCeCCeCCeCCeCCeECeCCaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeBceAZeAZeBaaaiaaiaaiaaieDTeEDeEBaaiaaiaaiaaiaaieAYeAZeAZeAZeBaaaiaaiaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeBleEEeEEeEEeDTeDTeDTeEFeDTeCzeDVeEGeBIeEHeEIeEJeEKeEKeELeEMeENeEOeEPaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeBleEEeEQeEReBIeBIeBIeBIeBIeESeETeEUeEUeDGeEVeEWeEVeEVeEVeEVeEXeEYeEZaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeBleEEeEEeFaeFbeDheDheDheFceFdeFeeDheDheFfeFgeFheEbeFjeEbeFkeFleFmeFnaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeCkeCleCleCmaaiaaiaaiaaieFoeFpeFqaaiaaiaaiaaieExeFseFteEbeFueFveFweFxaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaieFyeFzeFAeFBeFCeFDeFEeFFeFGaaieFmeFHeFmeFIeFmeFveFmeFmaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaieFJeFzeFKeFLeFMeFNeFOeFzeFPaaiaaieFQaaiaaiaaieFQaaiaaiaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaieFReFzeFSeFTeFUeFVeFWeFzeFXaaieFYeFZeFYaaieFYeFZeFYaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaieGaeGbeGceGdeGeeGfeGceGbeGgaaieFYeGheFYaaieFYeGieFYaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaieGjeGkeGleGleGmeGneGoeGpeGqaaieFYeFYeFYaaieFYeFYeFYaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaaiaaiaaieGreGsaaiaaieGtaaiaaieGueGvaaiaaiaaiaaiaaiaaiaaiaaiaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaieGweGxeGyeGzeGAaaieGBeGCeGDaaieGEeGFeGGeGHeGIaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaieGJeGKeGKeGKeGKaaieGLeGMeGNaaieGOeGPeGPeGPeGPaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaieGQeGReGSeGReGKaaieGNeGTeGNaaieGPeGPeGUeGPeGVaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeGWeGKeGXeGYeGZeGKaaiaaiaaiaaiaaieGPeGPeGPeGPeHaaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeBleGKeGKeGKeGKeGKeGWaaaaaaaaaaaieHbeHceHdeHeeHfaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeCkeAZeAZeAZeAZeAZeHgaaaaaaaaaaaiaaiaaiaaiaaiaaiaaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadvVeAReASeARdvVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadvVeATeAUeAVdvVeAWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadvVeAUeAUeAXdCadAdeBaeAZeAYdCadCaelGdDYdCgdCgdCgeBbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeCkeCjeCjeBleBceBceBceBceAReBdeARdCaeBeeBfeBgeBheBidCaeBjeBkeBkeBkeBkeClaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeCmeBmeBneBoeBpeBqeBreBseBteBueBveBweBxeByeBzeBgeBAdCaeBBeBkeBkeBkeBkeClaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeCmeBCeBDeBEeBFeBGeBGeBHeBIeBJeBKeBLeBMeBNeBOeBPeBQeBReBSeBkeBkeBkeBkeClaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeCmeBTeBUeBVeBWeBXeBYeBZeCaeCbeCceCdeCeeCfeCgeBgeChdCaeCieBkeBkeBkeBkeDlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeDCeDteDteDseBceBceBceBceCneCoeCpdCaeCqeCreCseCteCudCaeBkeCveCweCxeBkelGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadvVeCneCoeCydCadCaeBaeAZeAYdCadCaelGdDYdCgeDNelGelGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeEeeEdeEdeEdeEdeDWeEzeEzeEzeCneCzeCAeDdeCBeCCeCCeCCeCCeCDeCCeCCeCCeCEeCFeDdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeFoeCGeCGeCGeCGeCHeCIeCJeEzeCKeCLeCMeDdeCCeCNeCNeCOeCOeCCeCPeCQeCReCSeCTeFpeCVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeFoeCGeCGeCGeCGeCGeCGeCWeEzeCneCoeCXeDdeCYeCNeCNeCOeCOeCCeCZeDaeDbeDceCCeFqaaaeDdeDdeDdeDdeDdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeFoeCGeCHeDeeCHeDfeDgeDgeDgeDieDjeDkeFQeDmeDneDneDneDneDoeCPeDpeDbeDqeDreGseGreDueDveDweDxeDdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeFoeCGeDyeDeeCHeDzeDAeDBeGveDDeDEeDFeGueDHeCCeDIeCUeDKeCCeCCeCCeDLeCCeDMeGWaaaeDOeDPeDQeDxeDRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeFoeCGeCGeCGeCGeCGeCGeDSeEzeDTeDUeDVeHgeDXeDYeDYeDYeDYeDZeCQeCPeEaeDJeEceHEeHDeEfeEgeEheDxeDdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeFoeCGeCGeCGeCGeCGeEieEjeHHeBteEkeEleDdeEmeEneEoeEpeEpeCCeEqeDKeEreDreEseFqaaaeDdeDdeDdeDdeDdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeHKeHJeHJeHJeHJeHIeEzeEzeEzeEteEueEveDdeEweEneEoeEpeEpeCCeDpeCPeAieDreEyeHLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadvVeEAeCoeEBeDdeCCeECeCCeCCeCCeCCeCCeCCeCCeECeCCeDdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeHOeHNeHNeHMdvVdvVdvVdvVeDTeEDeEBeDdeDdeDdeDdeDdeHReHQeHQeHQeHPeDdeDdeDdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeHSeEEeEEeEEeDTeDTeDTeEFeDTeCzeDVeEGeBIeEHeEIeEJeEKeEKeELeEMeENeEOeEPeHTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeHSeEEeEQeEReBIeBIeBIeBIeBIeESeETeEUeEUeDGeEVeEWeEVeEVeEVeEVeEXeEYeEZeHTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeHSeEEeEEeFaeFbeDheDheDheFceFdeFeeDheDheFfeFgeFheEbeFjeEbeFkeFleFmeFneHTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeHXeHWeHWeHVeHUeHUeHUeHUeIaeHZeHYeHUeHUeHUeHUeExeFseFteEbeFueFveFweFxeHTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeHUeFyeFzeFAeFBeFCeFDeFEeFFeFGeHUeFmeFHeFmeFIeFmeFveFmeFmeHTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeHUeFJeFzeFKeFLeFMeFNeFOeFzeFPeHUeHTeIbeHTeHTeHTeIbeHTeHTeHTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeHUeFReFzeFSeFTeFUeFVeFWeFzeFXeHUeFYeFZeFYeHTeFYeFZeFYeHTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeHUeGaeGbeGceGdeGeeGfeGceGbeGgeHUeFYeGheFYeHTeFYeGieFYeHTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeHUeGjeGkeGleGleGmeGneGoeGpeGqeHUeFYeFYeFYeHTeFYeFYeFYeHTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeIceIceIceIceIfeIeeHUeHUeGteHUeHUeIdeIgeHUeIceIceIceHTeHTeHTeHTeHTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeIceGweGxeGyeGzeGAeHUeGBeGCeGDeHUeGEeGFeGGeGHeGIeIcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeIceGJeGKeGKeGKeGKeHUeGLeGMeGNeHUeGOeGPeGPeGPeGPeIcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeIceGQeGReGSeGReGKeHUeGNeGTeGNeHUeGPeGPeGUeGPeGVeIcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeIheGKeGXeGYeGZeGKeHUeHUeHUeHUeHUeGPeGPeGPeGPeHaeIcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeIieGKeGKeGKeGKeGKeIhaaaaaaaaaeIceHbeHceHdeHeeHfeIcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeIkeIjeIjeIjeIjeIjeIlaaaaaaaaaeIceIceIceIceIceIceIcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/nano/css/shared.css b/nano/css/shared.css index e10b38c6c41..02476dcb8f1 100644 --- a/nano/css/shared.css +++ b/nano/css/shared.css @@ -128,7 +128,7 @@ img, a img { h1, h2, h3, h4, h5, h6 { margin: 0; padding: 12px 0 6px 0; - color: #517087; + color: #FFFFFF; clear: both; } @@ -238,17 +238,32 @@ div.notice { clear: both; } -.itemLabel { +.itemLabel, .itemLabelWide { float: left; - width: 30%; color: #e9c183; } -.itemContent { - float: left; +.itemLabel { + width: 30%; +} + +.itemLabelWide { width: 69%; } + +.itemContent, .itemContentThin { + float: left; +} + +.itemContent { + width: 69%; +} + +.itemContentThin { + width: 30%; +} + .itemLabelNarrow { float: left; width: 20%; @@ -473,6 +488,14 @@ div.notice { text-align: center; } +table.fixed { + table-layout:fixed; +} + +table.fixed td { + overflow: hidden; +} + /* Table styling for the power monitor */ table.pmon { border: 2px solid RoyalBlue; diff --git a/nano/debug.html b/nano/debug.html index 969956bacb2..58b2be3df1a 100644 --- a/nano/debug.html +++ b/nano/debug.html @@ -16,7 +16,7 @@ - +